6.4.  Recursively access a directory tree

[Note]

The new FileVisitor Java 7 NIO.2 API allows you to implement scenario in which you want to traverse a directory tree recursively, stopping at each file and directory under that tree and having your own callback methods invoked for each entry found. In previous Java versions, this would have been a painful process involving recursively listing directories, inspecting their entries, and invoking the callbacks yourself. In Java 7, this is all provided via the FileVisitor API:


public interface FileVisitor<T> {

    FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs) throws IOException;

    FileVisitResult visitFile(T file, BasicFileAttributes attrs) throws IOException;

    FileVisitResult visitFileFailed(T file, IOException exc) throws IOException;

    FileVisitResult postVisitDirectory(T dir, IOException exc) throws IOException;
}


					

public enum FileVisitResult {
    /**
     * Continue. When returned from a FileVisitor#preVisitDirectory method then the entries in the
     * directory should also be visited.
     */
    CONTINUE,

    /**
     * Terminate.
     */
    TERMINATE,

    /**
     * Continue without visiting the entries in this directory. This result is only meaningful when
     * returned from the FileVisitor#preVisitDirectory method; otherwise this result type is the
     * same as returning CONTINUE.
     */
    SKIP_SUBTREE,

    /**
     * Continue without visiting the siblings of this file or directory. If returned from the
     * FileVisitor#preVisitDirectory method then the entries in the directory are also skipped
     * and the FileVisitor#postVisitDirectory method is not invoked.
     */
    SKIP_SIBLINGS;
}

					

The first step is to implement your own FileVisitor class. This class contains the callback methods that the file-visitor engine will invoke as it traverses the file system. The FileVisitor interface consists of four methods, listed here in the typical order they would be called during traversal (T here stands for either java.nio.file.Path or a superclass):

To help developers save time, NIO.2 has provided an implementation of the FileVisitor interface: java.nio.file.SimpleFileVisitor. This class is as basic as it gets: for the xxxxxFailed() methods, it just rethrows the exception, and for the other methods it continues without doing anything at all. What is useful about this class is that you can use anonymous classes to override only the methods you want; the rest of the methods are implemented by default.

Code below shows how to create anonymous inner FileVisitor instance:


FileVisitor<Path> myFileVisitor = new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
        System.out.println(String.format("Before visit the '%s' directory", dir));
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attribs) {
        System.out.println(String.format("Visiting file '%s' which has size %d bytes", file, attribs.size()));
        return FileVisitResult.CONTINUE;
    }
};

					

The FileVisitor implementation from code above should print a message for each directory and file it visits and also give the size of the files from their BasicFileAttributes.

Next we want to create a Path from which to start our file visiting. This is done using the java.nio.file.Paths class:

Path headDir = Paths.get("C:\\home");
					

We can use either of two methods on the java.nio.file.Files class to start the tree traversal:

We will use the simpler version of the walkFileTree(...) method to start the process of walking the file tree:

Files.walkFileTree(headDir, myFileVisitor);
					

it shows the output similar to this:

Before visit the 'C:\home' directory
Before visit the 'C:\home\zaikin' directory
Before visit the 'C:\home\zaikin\foo' directory
Before visit the 'C:\home\zaikin\foo\company' directory
Visiting file 'C:\home\zaikin\foo\company\readme.txt' which has size 2 bytes
Before visit the 'C:\home\zaikin\foo\sample' directory
Visiting file 'C:\home\zaikin\foo\test.txt' which has size 7 bytes
					

As you can see, the file traversal is depth first but not necessarily in any alphabetical order within a directory. Our callback methods were invoked as expected, and we can see that all the files in the tree have been listed and all the directories have been visited.

Professional hosting         Free 'Oracle Certified Expert Web Services Developer 6' Guide     Free SCDJWS 5.0 Guide