Oracle Blog

Learn Java & Thrive

Traversing a file tree in NIO.2

Have you downloaded JDK7 and played with NIO.2 yet? NIO.2 offers many new I/O features, particularly in the area of files and file system APIs. (To those of you who think, I can't use JDK7 because I am on a Mac: So am I. What I did was to download VirtualBox for my Mac (it's free). This allows you to set up a virtual environment on your machine. You can then download OpenSolaris, Ubuntu, or even Windows (but OpenSolaris and Ubuntu are free).

I wrote a simple example which you can use to find a file on your file system. (Think of a very simplified version of the Unix find.) The new java.nio.file.Files class provides a factory method, walkFileTree, you can use to traverse a tree of directories and files. When you invoke this method, you specify the root and how many levels deep you want to go. You can also set an attribute to indicate that it should follow links.

The meat of the work occurs in a class you create that implements the java.nio.file.FileVisitor interface. This interface has hooks for before, during, and after a file is "visited", as well as for when failure occurs. In my simple Find example, when the file is visited, the file name is compared to the user-specified name. If it matches, the full path is printed to stdout.

You create an instance of this class and pass it to the walkFileTree method. For each file or directory in the tree, the instance is invoked. You will notice that in this example, CONTINUE is returned in each of the FileVisitor methods. You can also return SKIP_SUBTREE or SKIP_SIBLINGS to terminate progress when necessary.

That's it.

If you download the NIO.2 JDK7 binaries, you will find other NIO.2 examples. Three of them also use the walkFileTree method: Chmod.java, Copy.java and WatchDir.java.

Update: This code has been slightly modified from when it was originally posted a few days ago. Originally, it compared the file names using the String class, but this may not provide the right result on some file systems. The comparison has been changed to the Path.equals method, which takes the type of file system into account.

Also, the example originally would only match files and not directories. By adding the comparison to the preVisitDirectory method, both files and directories will be examined.