The Java Tutorials' Weblog
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.
To call Find: java Find path file.
Here is the code for
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
Also, the example originally would only match files and not directories. By adding the comparison to the
-- Sharon Zakhour
Posted at
09:47AM Mar 24, 2009
by The Java Tutorial Team |
Comments[3]
Find.java:
/**
* Sample code that finds files. Similar to the find(1) program, but simplified.
*/
public class Find {
/**
* A {@code FileVisitor} that finds a file.
*/
static class Finder implements FileVisitor
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.
preVisitDirectory method, both files and directories will be examined.
Tuesday Mar 24, 2009
Sharon - good to see you are having fun with this. Note that find doesn't follow links by default so what you've implemented is closer to "find -follow" or "find -L". In any case, the important point about following links is cycles will be detected (and reported). This is important for operations like recursive copy where you need to follow links (for most other recursive operations you don't want to follow links). Another thing to mention is that the Path equals methods knows how to compare path based on the rules for the platform and so is more correct than String comparison. Alternatively, try out PathMatcher as that would allow you implement find's "-name <pattern>".
Posted by Alan on March 26, 2009 at 02:17 AM PDT #
Link to virtualbox should not have a quote at the end of it
Posted by Chris on March 26, 2009 at 08:19 AM PDT #
Thanks, Chris, I fixed the link.
Thanks for your comments, Alan. :)
Posted by Sharon Zakhour on March 26, 2009 at 02:37 PM PDT #