Skip to content

Yet another programming solutions log

Sample bits from programming for the future generations.

Technologies Technologies
  • Algorithms and Data Structures
  • Java Tutorials
  • JUnit Tutorial
  • MongoDB Tutorial
  • Quartz Scheduler Tutorial
  • Spock Framework Tutorial
  • Spring Framework
  • Bash Tutorial
  • Clojure Tutorial
  • Design Patterns
  • Developer’s Tools
  • Productivity
  • About
Expand Search Form

Java 7 Walk File Tree

farenda 2016-04-11 0

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.

Solution:

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.

package com.farenda.java.nio;

import java.io.IOException;
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;

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

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

        @Override
        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");

        calculateSizeNaively(path);

        calculateSizeByWalkingTree(path);
    }

    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/diagnostic.data 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!
Categories Java Tags java, java-io
Previous: Spring @Value default value
Next: Java 8 Find Files

Recent Posts

  • Java 8 Date Time concepts
  • Maven dependency to local JAR
  • Caesar cipher in Java
  • Java casting trick
  • Java 8 flatMap practical example
  • Linked List – remove element
  • Linked List – insert element at position
  • Linked List add element at the end
  • Create Java Streams
  • Floyd Cycle detection in Java

Pages

  • About Farenda
  • Algorithms and Data Structures
  • Bash Tutorial
  • Bean Validation Tutorial
  • Clojure Tutorial
  • Design Patterns
  • Java 8 Streams and Lambda Expressions Tutorial
  • Java Basics Tutorial
  • Java Collections Tutorial
  • Java Concurrency Tutorial
  • Java IO Tutorial
  • Java Tutorials
  • Java Util Tutorial
  • Java XML Tutorial
  • JUnit Tutorial
  • MongoDB Tutorial
  • Quartz Scheduler Tutorial
  • Software Developer’s Tools
  • Spock Framework Tutorial
  • Spring Framework

Tags

algorithms bash bean-validation books clojure design-patterns embedmongo exercises git gof gradle groovy hateoas hsqldb i18n java java-basics java-collections java-concurrency java-io java-lang java-time java-util java-xml java8 java8-files junit linux lists log4j logging maven mongodb performance quartz refactoring regex rest slf4j solid spring spring-boot spring-core sql unit-tests

Yet another programming solutions log © 2021

sponsored