Files.walkFileTree visits a directory tree through callbacks that distinguish entry visits, directory entry, failed visits, and directory completion. A complete inventory must define what happens when any visit fails.
Java walkFileTree: visit failures without hiding incomplete scans
Operational contract
A manifest scanner should not return a green count after permission failure halfway through a tree. SimpleFileVisitor's default failure behavior throws, which is useful when completeness matters. If the application deliberately skips a subtree, it must record the omitted path and mark the inventory partial. The visitor below collects regular files without following symbolic links and lets I/O failures reach the caller. The caller owns the resulting list and the decision to publish it.
Failure case
A fictional dispatch archive has 47 manifest files under several depot folders. If one depot cannot be opened, a count of the other files is not an archive total. Keep that failure beside the scan ID; do not silently treat it as an empty folder. Following directory links would also change the traversal boundary and could create cycles, so the sample retains the default no-follow behavior.
Java code
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
public class ManifestTreeInventory {
public static List<Path> scan(Path archiveRoot) throws IOException {
List<Path> manifests = new ArrayList<>();
Files.walkFileTree(archiveRoot, new SimpleFileVisitor<Path>() {
@Override public FileVisitResult visitFile(Path path, BasicFileAttributes attributes) {
if (attributes.isRegularFile() && path.getFileName().toString().endsWith(".manifest")) {
manifests.add(path);
}
return FileVisitResult.CONTINUE;
}
@Override public FileVisitResult visitFileFailed(Path path, IOException failure) throws IOException {
throw new IOException("Inventory incomplete at " + path, failure);
}
});
return manifests;
}
}Performance and ownership cost
The walk visits N reachable entries in O(N) time. The visitor retains M matching paths in O(M) application memory; traversal bookkeeping grows with depth. A failure is a correctness result, not a performance detail. For huge trees, write bounded inventory records to a controlled sink rather than retaining every path.
Common Mistakes
- Do not convert visitFileFailed into CONTINUE without recording a partial result.
- Do not call a symlink target part of the scan unless link traversal is an explicit policy.
- Do not publish a total before traversal completes.
Connected lessons
- Java file I/O: UTF-8, streaming reads, and path ownership
- Java Files.walk: close the stream that owns directory handles
- Java Path.normalize: reject lexical escapes without promising symlink safety
- Java WatchService: register, consume, and reset each key
- Java WatchService OVERFLOW: reconcile against directory state
- Java DirectoryStream: close iteration and reject silent truncation
- Java symbolic links: inspect attributes without claiming race safety
- Java file, JDBC, and subprocess boundaries quiz
- Advanced Java
