• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..01-Sep-2019-

compare/H01-Sep-2019-3731

examples/H01-Sep-2019-9283

src/H01-Sep-2019-1,7501,160

.cargo-checksum.jsonH A D01-Sep-20191.3 KiB11

.travis.ymlH A D01-Sep-2019168 1413

COPYINGH A D01-Sep-2019126 42

Cargo.tomlH A D01-Sep-2019644 2521

LICENSE-MITH A D01-Sep-20191.1 KiB2217

MakefileH A D01-Sep-2019253 1511

README.mdH A D01-Sep-20194 KiB141102

UNLICENSEH A D01-Sep-20191.2 KiB2520

appveyor.ymlH A D01-Sep-2019537 2419

ctags.rustH A D01-Sep-2019902 1211

session.vimH A D01-Sep-201956 21

README.md

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[![Linux build status](https://api.travis-ci.org/BurntSushi/walkdir.svg)](https://travis-ci.org/BurntSushi/walkdir)
9[![Windows build status](https://ci.appveyor.com/api/projects/status/github/BurntSushi/walkdir?svg=true)](https://ci.appveyor.com/project/BurntSushi/walkdir)
10[![](http://meritbadge.herokuapp.com/walkdir)](https://crates.io/crates/walkdir)
11
12Dual-licensed under MIT or the [UNLICENSE](http://unlicense.org).
13
14### Documentation
15
16[docs.rs/walkdir](https://docs.rs/walkdir/)
17
18### Usage
19
20To use this crate, add `walkdir` as a dependency to your project's
21`Cargo.toml`:
22
23```
24[dependencies]
25walkdir = "1"
26```
27
28### Example
29
30The following code recursively iterates over the directory given and prints
31the path for each entry:
32
33```rust,no_run
34use walkdir::WalkDir;
35
36for entry in WalkDir::new("foo") {
37    let entry = entry.unwrap();
38    println!("{}", entry.path().display());
39}
40```
41
42Or, if you'd like to iterate over all entries and ignore any errors that may
43arise, use `filter_map`. (e.g., This code below will silently skip directories
44that the owner of the running process does not have permission to access.)
45
46```rust,no_run
47use walkdir::WalkDir;
48
49for entry in WalkDir::new("foo").into_iter().filter_map(|e| e.ok()) {
50    println!("{}", entry.path().display());
51}
52```
53
54### Example: follow symbolic links
55
56The same code as above, except `follow_links` is enabled:
57
58```rust,no_run
59use walkdir::WalkDir;
60
61for entry in WalkDir::new("foo").follow_links(true) {
62    let entry = entry.unwrap();
63    println!("{}", entry.path().display());
64}
65```
66
67### Example: skip hidden files and directories efficiently on unix
68
69This uses the `filter_entry` iterator adapter to avoid yielding hidden files
70and directories efficiently:
71
72```rust,no_run
73use walkdir::{DirEntry, WalkDir, WalkDirIterator};
74
75fn is_hidden(entry: &DirEntry) -> bool {
76    entry.file_name()
77         .to_str()
78         .map(|s| s.starts_with("."))
79         .unwrap_or(false)
80}
81
82let walker = WalkDir::new("foo").into_iter();
83for entry in walker.filter_entry(|e| !is_hidden(e)) {
84    let entry = entry.unwrap();
85    println!("{}", entry.path().display());
86}
87```
88
89### Motivation
90
91`std::fs` has an unstable `walk_dir` implementation that needed some design
92work. I started off on that task, but it quickly became apparent that walking
93a directory recursively is quite complex and may not be a good fit for `std`
94right away.
95
96This should at least resolve most or all of the issues reported here (and then
97some):
98
99* https://github.com/rust-lang/rust/issues/27707
100* https://github.com/rust-lang/rust/issues/23715
101
102### Performance
103
104The short story is that performance is comparable with `find` and glibc's
105`nftw` on both a warm and cold file cache. In fact, I cannot observe any
106performance difference after running `find /`, `walkdir /` and `nftw /` on my
107local file system (SSD, ~3 million entries). More precisely, I am reasonably
108confident that this crate makes as few system calls and close to as few
109allocations as possible.
110
111I haven't recorded any benchmarks, but here are some things you can try with a
112local checkout of `walkdir`:
113
114```
115# The directory you want to recursively walk:
116DIR=$HOME
117
118# If you want to observe perf on a cold file cache, run this before *each*
119# command:
120sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'
121
122# To warm the caches
123find $DIR
124
125# Test speed of `find` on warm cache:
126time find $DIR
127
128# Compile and test speed of `walkdir` crate:
129cargo build --release --example walkdir
130time ./target/release/examples/walkdir $DIR
131
132# Compile and test speed of glibc's `nftw`:
133gcc -O3 -o nftw ./compare/nftw.c
134time ./nftw $DIR
135
136# For shits and giggles, test speed of Python's (2 or 3) os.walk:
137time python ./compare/walk.py $DIR
138```
139
140On my system, the performance of `walkdir`, `find` and `nftw` is comparable.
141