Example: Directory Walking with ddn.os.path.Path¶
This example demonstrates how to use the ddn.os.path.Path module to iterate over directories and files, perform recursive walks, and apply custom pruning logic. The code is based on the demo.os.path_walk demo.
Overview¶
The Path struct provides convenient methods for directory iteration and recursive walking, similar to Python's os.walk. This example shows how to:
- List directory contents (shallow and recursive)
- Walk directories in top-down and bottom-up order
- Prune directories during traversal
- Handle symlinks (on POSIX systems)
Example Code¶
#! /usr/bin/env dub
/+ dub.sdl:
name "os-path-walk"
dependency "ddn" version=">=1.0.0"
+/
/**
* Demo: directory iteration and walking with ddn.os.path.Path
*
* Run:
* ./demo.sh demo-os-path_walk
* or:
* dub run --single demo/os/path_walk.d
*/
module demo.os.path_walk;
import std.stdio;
import std.file;
import std.path;
import std.algorithm;
import std.array;
import std.uuid : randomUUID;
import ddn.os.path;
void main() {
writeln("=== ddn.os.path.walk demo ===");
// Create a temporary directory tree
auto base = buildPath("tmp_demo_walk_" ~ randomUUID().toString());
scope (exit) { if (exists(base)) rmdirRecurse(base); }
Path(buildPath(base, "sub", "nested")).mkdir(true);
Path(buildPath(base, "skip")).mkdir(true);
Path(buildPath(base, ".hidden")).mkdir(true);
Path(buildPath(base, "a.txt")).writeText("A\n");
Path(buildPath(base, "sub", "b.txt")).writeText("B\n");
Path(buildPath(base, "sub", "nested", "c.txt")).writeText("C\n");
version (Posix) {
// best-effort: a symlink to sub
Path(buildPath(base, "link")).symlinkTo("sub");
}
auto root = Path(base);
writeln("-- iterdir() (shallow)");
foreach (p; root.iterdir()) {
writeln(" ", baseName(p.str()));
}
writeln("-- walk(topDown=true)");
foreach (e; root.walk(true, false)) {
writeln(" [", e.root.str(), "]");
if (e.dirs.length) {
writeln(" dirs: ", e.dirs.map!(d => baseName(d.str())).array);
}
if (e.files.length) {
writeln(" files: ", e.files.map!(f => baseName(f.str())).array);
}
}
writeln("-- walk(topDown=false)");
foreach (e; root.walk(false, false)) {
writeln(" ", e.root.str());
}
writeln("-- walk with pruning (skip directory named 'skip')");
bool delegate(const Path) prune = (const Path p) {
return baseName(p.str()) != "skip";
};
foreach (e; root.walk(true, false, prune)) {
writeln(" ", e.root.str());
}
version (Posix) {
writeln("-- walk(followSymlinks=true)");
foreach (e; root.walk(true, true)) {
// just enumerate; loop protection prevents cycles
writeln(" ", e.root.str());
}
}
writeln("=== End walk demo ===");
}
Key Points¶
- Shallow Iteration: Use
iterdir()to list immediate children of a directory. - Recursive Walk: Use
walk(topDown, followSymlinks)to traverse directories recursively. - Pruning: Pass a delegate to
walkto skip certain directories (e.g., by name). - Symlink Handling: On POSIX systems, you can follow symlinks safely with loop protection.
Output Example¶
The output will show the structure of the temporary directory tree, including directories, files, and the effect of pruning and symlink following.