All 15 I/O & NIO questions
More in I/O & NIO
Advertisement
Java › I/O & NIO

How would you recursively copy an entire directory tree (including all subdirectories and files) using the Files.walkFileTree() method and a FileVisitor implementation?

Intermediate

Answer

Files.walkFileTree(startPath, visitor) traverses an entire directory tree, invoking callback methods on a supplied FileVisitor implementation at specific points (preVisitDirectory before entering a directory, visitFile for each regular file, postVisitDirectory after finishing a directory, and visitFileFailed if an error occurs accessing a particular file) -- implementing a recursive copy involves creating the corresponding destination directory structure in preVisitDirectory and copying each individual file's content in visitFile, giving fine-grained control over the traversal (like selectively skipping certain subdirectories) that a simpler flat directory listing wouldn't provide.
Files.walkFileTree(sourceDir, new SimpleFileVisitor<Path>() {
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
        Path targetDir = destDir.resolve(sourceDir.relativize(dir));
        Files.createDirectories(targetDir);
        return FileVisitResult.CONTINUE;
    }
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        Files.copy(file, destDir.resolve(sourceDir.relativize(file)), StandardCopyOption.REPLACE_EXISTING);
        return FileVisitResult.CONTINUE;
    }
});
Real-world example A backup utility recursively copies an entire project directory (preserving its full subdirectory structure) using Files.walkFileTree() with a custom FileVisitor, additionally skipping any directory named 'node_modules' or '.git' by returning FileVisitResult.SKIP_SUBTREE from preVisitDirectory for those specific directory names.

Common follow-ups: How does Files.walk() (returning a Stream<Path>) compare to Files.walkFileTree() in terms of flexibility and use case fit?;What's the purpose of the FileVisitResult return value, and what other options besides CONTINUE exist?