File System Operations
File Metadata
std::fs::Metadata represents the filesystem attributes of a file, directory, or symbolic link—including its byte length, entry type (FileType), permissions (Permissions), and modification/access/creation timestamps (SystemTime).
Three Ways to Query Metadata (Symlink-Following vs. Non-Following)
| Function / Method | Follows Symbolic Links? | OS Syscall Equivalent | When to Use |
|---|---|---|---|
fs::metadata(path) |
Yes (queries the target of a symlink; fails with NotFound on a broken symlink) |
stat (Unix) / GetFileAttributesEx |
Inspecting the actual file a path resolves to |
fs::symlink_metadata(path) |
No (queries the symlink entry itself!) | lstat (Unix) |
Detecting symlinks (meta.is_symlink()) or inspecting broken symlinks |
file.metadata() |
Queries the already-open file descriptor | fstat (Unix) |
Avoids path lookup overhead and TOCTOU path races when a File is already open! |
Given Symlink: `latest.log -> app-2026.log` (1,024 bytes)
`fs::metadata("latest.log")`
+-- Follows symlink to `app-2026.log`:
`.is_file() == true`, `.is_symlink() == false`, `.len() == 1024`
`fs::symlink_metadata("latest.log")`
+-- Inspects symlink entry itself:
`.is_file() == false`, `.is_symlink() == true`
Key Methods on std::fs::Metadata
| Method | Return Type | Description |
|---|---|---|
.len() |
u64 |
Size of the file in bytes |
.is_file() |
bool |
true if regular file |
.is_dir() |
bool |
true if directory |
.is_symlink() |
bool |
true if symbolic link (only possible via fs::symlink_metadata or DirEntry::metadata!) |
.file_type() |
FileType |
Detailed file type (extensible via std::os::unix::fs::FileTypeExt for sockets/FIFOs/devices) |
.permissions() |
Permissions |
Read-only flag and OS permission mode |
.modified() |
io::Result<SystemTime> |
Last modification timestamp (mtime) |
.accessed() |
io::Result<SystemTime> |
Last access timestamp (atime) |
.created() |
io::Result<SystemTime> |
Creation / birth timestamp (btime, supported on macOS, Windows, and modern Linux statx) |
use std::fs::{self, File};
use std::io::{self, Write};
use std::time::SystemTime;
fn main() -> io::Result<()> {
let path = std::env::temp_dir().join("rust_ch50_metadata_demo.txt");
{
let mut f = File::create(&path)?;
f.write_all(b"0123456789ABCDEF")?;
// Query metadata directly on the open file descriptor (`fstat`):
let fd_meta = f.metadata()?;
println!("via file.metadata() -> len = {} bytes", fd_meta.len());
}
let meta = fs::metadata(&path)?;
let modified_age = SystemTime::now()
.duration_since(meta.modified()?)
.unwrap_or_default();
println!(
"is_file: {}, is_dir: {}, is_symlink: {}, modified <= 5s ago: {}",
meta.is_file(),
meta.is_dir(),
meta.is_symlink(),
modified_age.as_secs() <= 5
);
fs::remove_file(&path)?;
Ok(())
}
via file.metadata() -> len = 16 bytes
is_file: true, is_dir: false, is_symlink: false, modified <= 5s ago: true