Programming for fun and profit

Programming tutorials, problems, solutions. Always with code.

Java 7 Walk File Tree

Java Files.walkFileTree() exmaple

In this post we’re going to show how use FileVisitor and Files from Java 7 NIO to walk directory tree and calculate sizes of its directories.

To walk directory tree we’re going to use a few classes and interfaces:

  • SimpleFileVisitor
    Provides default implementation of FileVisitor interface to remove from subclasses a need to implement all the methods;
  • Files.walkFileTree()
    The method that does all the hard work of traversing directory tree and calling our FileVisitor
  • BasicFileAttributes
    File metadata described in one of previous posts.


In this example we’re going to implement own FileVisitor that will count size of each directory in specified path. The method calculateSizeNaively() shows that Files.size(dir) won’t return true directory size, but only size of its file descriptor. To measure real size, we have to walk directory tree and sum sizes of all its members – we do this in the second method.


import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.LinkedList;
import java.util.Queue;

import static java.util.Collections.asLifoQueue;

public class WalkFileTreeExample {

    public static class FileSizeCalculator extends SimpleFileVisitor<Path> {

        private Queue<Long> sizesOfParents
                = asLifoQueue(new LinkedList<>());
        private long currentDirSize;

        public FileVisitResult preVisitDirectory(
                Path dir, BasicFileAttributes attrs)
                throws IOException {
            currentDirSize = 0;
            return FileVisitResult.CONTINUE;

        public FileVisitResult visitFile(
                Path file, BasicFileAttributes attrs)
                throws IOException {
            currentDirSize += attrs.size();
            return FileVisitResult.CONTINUE;

        public FileVisitResult postVisitDirectory(
                Path dir, IOException e) throws IOException {
            displaySize(dir, currentDirSize);
            currentDirSize += sizesOfParents.remove();
            return FileVisitResult.CONTINUE;

    public static void main(String[] args) throws IOException {
        Path path = Paths.get("/var/lib/mongodb");



    private static void calculateSizeNaively(Path path)
            throws IOException {
        System.out.println("Naive Files.size(dir) version:");
        displaySize(path, Files.size(path));

    private static void calculateSizeByWalkingTree(Path path)
            throws IOException {
        System.out.println("\nUsing FileVisitor:");
        FileSizeCalculator calculator
            = new FileSizeCalculator();
        Files.walkFileTree(path, calculator);

    private static void displaySize(Path dir, long size) {
        System.out.printf("Directory %s size: %d KB%n",
                dir, (size / 1024));

Note that FileVisitor methods return FileVisitResult to indicate what to do next. We just continue the walk, but there are a few more options:

  • FileVisitResult.CONTINUE
    Continue the walk.
  • FileVisitResult.SKIP_SIBLINGS
    Skip siblings to this file/directory. If called from preVisitDirectory() will also skip the current file/directory.
  • FileVisitResult.SKIP_SUBTREE
    Skip current directory (only makes sense from preVisitDirectory()).
  • FileVisitResult.TERMINATE
    Stop the walk.

Skip options are useful to do filtering – for example to process only files/directories matching a regular expression.

Also note the use of Collections.asLifoQueue() to implement stack – learn more about this in Java Deque Stack Queue post!

And here’s the result of running the above code to count size of MongoDB 3 directory:

Naive Files.size(dir) version:
Directory /var/lib/mongodb size: 4 KB

Using FileVisitor:
Directory /var/lib/mongodb/ size: 2866 KB
Directory /var/lib/mongodb/journal size: 3145728 KB
Directory /var/lib/mongodb size: 4639538 KB

Naive version is clearly wrong. :-)

Share with the World!