File System Operations
read_dir()
std::fs::read_dir(path) -> io::Result<ReadDir> opens a directory at path and returns a ReadDir iterator that yields io::Result<DirEntry> for each child entry inside the directory (automatically excluding the special . current-directory and .. parent-directory entries).
Why read_dir Has Two Layers of io::Result
Notice that both fs::read_dir(path) and each item yielded by ReadDir return an io::Result:
- Outer
io::Result<ReadDir>: Fails immediately ifpathdoes not exist (NotFound), is not a directory (NotADirectory), or the process lacks read permission onpath(PermissionDenied). - Inner
Iterator<Item = io::Result<DirEntry>>: Fails if an OS I/O error occurs mid-iteration while reading subsequent directory blocks from disk or a network filesystem.
Methods on std::fs::DirEntry
DirEntry Method |
Signature | Extra OS Syscall on Unix/Windows? | Description |
|---|---|---|---|
.path(&self) |
pub fn path(&self) -> PathBuf |
No | Returns the full path (joining the argument passed to read_dir with .file_name()) |
.file_name(&self) |
pub fn file_name(&self) -> OsString |
No | Returns only the bare filename component ("Cargo.toml") |
.file_type(&self) |
pub fn file_type(&self) -> io::Result<FileType> |
No (on Windows and most Unix filesystems) | Returns FileType (.is_dir(), .is_file(), .is_symlink()) without following symlinks |
.metadata(&self) |
pub fn metadata(&self) -> io::Result<Metadata> |
No on Windows; lstat syscall on Unix |
Returns file size, permissions, and timestamps (without following symlinks) |
use std::fs;
use std::io;
fn main() -> io::Result<()> {
let dir = std::env::temp_dir().join("rust_ch50_readdir_demo");
fs::create_dir_all(&dir)?;
fs::write(dir.join("config.toml"), "port = 8080\n")?;
fs::create_dir_all(dir.join("logs"))?;
let mut entries: Vec<(String, &'static str)> = Vec::new();
for entry_res in fs::read_dir(&dir)? {
let entry = entry_res?;
let name = entry.file_name().to_string_lossy().into_owned();
let ft = entry.file_type()?;
let kind = if ft.is_dir() {
"dir"
} else if ft.is_file() {
"file"
} else {
"symlink/other"
};
entries.push((name, kind));
}
entries.sort();
for (name, kind) in entries {
println!("{:<14} ({})", name, kind);
}
fs::remove_dir_all(&dir)?;
Ok(())
}
config.toml (file)
logs (dir)