Install walkdir via Cargo
masterTo use walkdir in your Rust project, add it to your Cargo.toml dependencies file.
[dependencies]
walkdir = "2"repository·master·Indexed 23 days ago
https://github.com/burntsushi/walkdirA cross-platform Rust library for efficient recursive directory traversal. Version 2.5.0 provides features such as symbolic link following, control over open file descriptors via `max_open`, and efficient directory tree pruning using `filter_entry`. It includes the `WalkDir` builder for configuring depth, sorting, and filesystem boundaries, and the `DirEntry` struct for accessing file paths, metadata, and inode numbers on Unix systems.
To use walkdir in your Rust project, add it to your Cargo.toml dependencies file.
[dependencies]
walkdir = "2"The WalkDir type acts as a builder. You use it to configure traversal options (depth, symlinks, sorting, etc.). Once configured, you call .into_iter() to consume the builder and produce an IntoIter instance.
IntoIter is the actual iterator that performs the traversal. It implements Iterator<Item = Result<DirEntry>>. Because it returns a Result, you must handle potential I/O errors during the loop.
When walking directories, you may need to distinguish between symbolic links and their targets.
path_is_symlink(): Returns true if the entry was created from a symbolic link. This result is unaffected by the follow_links setting of the iterator. If this returns true, the path() method returns the name of the symbolic link.path_is_symlink() with std::fs::read_link():if entry.path_is_symlink() {
let target = std::fs::read_link(entry.path())?;
println!("Link target: {:?}", target);
}By default, walkdir does not follow symbolic links. To enable following them, call .follow_links(true) on the WalkDir builder.
use walkdir::WalkDir;
for entry in WalkDir::new("foo").follow_links(true) {
let entry = entry.unwrap();
println!("{}", entry.path().display());
}To skip specific files or entire directories efficiently (preventing the walker from even descending into them), use the filter_entry iterator adapter. This is more efficient than filtering entries after they have been yielded, as it prunes the tree during traversal.
use walkdir::{DirEntry, WalkDir};
fn is_hidden(entry: &DirEntry) -> bool {
entry.file_name()
.to_str()
.map(|s| s.starts_with("."))
.unwrap_or(false)
}
let walker = WalkDir::new("foo").into_iter();
for entry in walker.filter_entry(|e| !is_hidden(e)) {
let entry = entry.unwrap();
println!("{}", entry.path().display());
}Use WalkDir::new("path") to create a new walker. You can iterate over the entries using a for loop. Note that each iteration returns a Result<DirEntry, Error>, so you must handle potential errors (e.g., using .unwrap() or pattern matching).
use walkdir::WalkDir;
for entry in WalkDir::new("foo") {
let entry = entry.unwrap();
println!("{}", entry.path().display());
}If you want to skip entries that cause errors (such as directories where the process lacks permission), use .into_iter().filter_map(|e| e.ok()) on the WalkDir instance.
use walkdir::WalkDir;
for entry in WalkDir::new("foo").into_iter().filter_map(|e| e.ok()) {
println!("{}", entry.path().display());
}rustc version for walkdir is 1.60.0. The project follows a policy where minor version updates (e.g., 1.0.z) maintain the same minimum requirement, but minor version increments (e.g., 1.y where y > 0) may increase the minimum required Rust version.To avoid descending into specific directories (like hidden ones), use the .filter_entry() iterator adapter. This is more efficient than standard filter() because it prevents the iterator from even recursing into directories that fail the predicate.
use walkdir::{DirEntry, WalkDir};
fn is_hidden(entry: &DirEntry) -> bool {
entry.file_name()
.to_str()
.map(|s| s.starts_with("."))
.unwrap_or(false)
}
let walker = WalkDir::new("foo").into_iter();
for entry in walker.filter_entry(|e| !is_hidden(e)) {
println!("{}", entry?.path().display());
}use walkdir::{DirEntry, WalkDir};
# use walkdir::Error;
fn is_hidden(entry: &DirEntry) -> bool {
entry.file_name()
.to_str()
.map(|s| s.starts_with("."))
.unwrap_or(false)
}
# fn try_main() -> Result<(), Error> {
let walker = WalkDir::new("foo").into_iter();
for entry in walker.filter_entry(|e| !is_hidden(e)) {
println!("{}", entry?.path().display());
}
# Ok(())
# }By default, symbolic links are not followed. To follow them, use the .follow_links(true) method on the WalkDir builder. Note that if a symbolic link is broken or involved in a loop, an error will be yielded.
use walkdir::WalkDir;
for entry in WalkDir::new("foo").follow_links(true) {
println!("{}", entry?.path().display());
}use walkdir::WalkDir;
# use walkdir::Error;
# fn try_main() -> Result<(), Error> {
for entry in WalkDir::new("foo").follow_links(true) {
println!("{}", entry?.path().display());
}
# Ok(())
# }If you want to iterate over all entries and silently skip any errors (such as directories you do not have permission to access), use filter_map on the iterator produced by into_iter().
use walkdir::WalkDir;
for entry in WalkDir::new("foo").into_iter().filter_map(|e| e.ok()) {
println!("{}", entry.path().display());
}Use WalkDir::new(path) to create a builder for a recursive directory iterator. The iterator yields entries in depth-first order, with directories yielded before their contents. Each iteration returns a Result<DirEntry>, so you should handle potential errors (e.g., permission issues) during iteration.
use walkdir::WalkDir;
for entry in WalkDir::new("foo") {
let entry = entry.unwrap();
println!("{}", entry.path().display());
}use walkdir::WalkDir;
# use walkdir::Error;
# fn try_main() -> Result<(), Error> {
for entry in WalkDir::new("foo") {
println!("{}", entry?.path().display());
}
# Ok(())
# }