• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1walkdir
2=======
3A cross platform Rust library for efficiently walking a directory recursively.
4Comes with support for following symbolic links, controlling the number of
5open file descriptors and efficient mechanisms for pruning the entries in the
6directory tree.
7
8[![Build status](https://github.com/BurntSushi/walkdir/workflows/ci/badge.svg)](https://github.com/BurntSushi/walkdir/actions)
9[![](https://meritbadge.herokuapp.com/walkdir)](https://crates.io/crates/walkdir)
10
11Dual-licensed under MIT or the [UNLICENSE](https://unlicense.org/).
12
13### Documentation
14
15[docs.rs/walkdir](https://docs.rs/walkdir/)
16
17### Usage
18
19To use this crate, add `walkdir` as a dependency to your project's
20`Cargo.toml`:
21
22```toml
23[dependencies]
24walkdir = "2"
25```
26
27### Example
28
29The following code recursively iterates over the directory given and prints
30the path for each entry:
31
32```rust,no_run
33use walkdir::WalkDir;
34
35for entry in WalkDir::new("foo") {
36    let entry = entry.unwrap();
37    println!("{}", entry.path().display());
38}
39```
40
41Or, if you'd like to iterate over all entries and ignore any errors that may
42arise, use `filter_map`. (e.g., This code below will silently skip directories
43that the owner of the running process does not have permission to access.)
44
45```rust,no_run
46use walkdir::WalkDir;
47
48for entry in WalkDir::new("foo").into_iter().filter_map(|e| e.ok()) {
49    println!("{}", entry.path().display());
50}
51```
52
53### Example: follow symbolic links
54
55The same code as above, except `follow_links` is enabled:
56
57```rust,no_run
58use walkdir::WalkDir;
59
60for entry in WalkDir::new("foo").follow_links(true) {
61    let entry = entry.unwrap();
62    println!("{}", entry.path().display());
63}
64```
65
66### Example: skip hidden files and directories efficiently on unix
67
68This uses the `filter_entry` iterator adapter to avoid yielding hidden files
69and directories efficiently:
70
71```rust,no_run
72use walkdir::{DirEntry, WalkDir};
73
74fn is_hidden(entry: &DirEntry) -> bool {
75    entry.file_name()
76         .to_str()
77         .map(|s| s.starts_with("."))
78         .unwrap_or(false)
79}
80
81let walker = WalkDir::new("foo").into_iter();
82for entry in walker.filter_entry(|e| !is_hidden(e)) {
83    let entry = entry.unwrap();
84    println!("{}", entry.path().display());
85}
86```
87
88### Minimum Rust version policy
89
90This crate's minimum supported `rustc` version is `1.34.0`.
91
92The current policy is that the minimum Rust version required to use this crate
93can be increased in minor version updates. For example, if `crate 1.0` requires
94Rust 1.20.0, then `crate 1.0.z` for all values of `z` will also require Rust
951.20.0 or newer. However, `crate 1.y` for `y > 0` may require a newer minimum
96version of Rust.
97
98In general, this crate will be conservative with respect to the minimum
99supported version of Rust.
100
101### Performance
102
103The short story is that performance is comparable with `find` and glibc's
104`nftw` on both a warm and cold file cache. In fact, I cannot observe any
105performance difference after running `find /`, `walkdir /` and `nftw /` on my
106local file system (SSD, ~3 million entries). More precisely, I am reasonably
107confident that this crate makes as few system calls and close to as few
108allocations as possible.
109
110I haven't recorded any benchmarks, but here are some things you can try with a
111local checkout of `walkdir`:
112
113```sh
114# The directory you want to recursively walk:
115DIR=$HOME
116
117# If you want to observe perf on a cold file cache, run this before *each*
118# command:
119sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'
120
121# To warm the caches
122find $DIR
123
124# Test speed of `find` on warm cache:
125time find $DIR
126
127# Compile and test speed of `walkdir` crate:
128cargo build --release --example walkdir
129time ./target/release/examples/walkdir $DIR
130
131# Compile and test speed of glibc's `nftw`:
132gcc -O3 -o nftw ./compare/nftw.c
133time ./nftw $DIR
134
135# For shits and giggles, test speed of Python's (2 or 3) os.walk:
136time python ./compare/walk.py $DIR
137```
138
139On my system, the performance of `walkdir`, `find` and `nftw` is comparable.
140