Masoud Kalali has a software engineering degree and has been working on software development projects since 1998. He has experience with a variety of technologies (.NET, J2EE, CORBA, and COM+) on diverse platforms (Solaris, Linux, and Windows). His experience is in software architecture, design, and server-side development.

Masoud has published several articles at Java.net and Dzone. He has authored multiple refcards, published by Dzone, including but not limited to Using XML in Java, Java EE Security and GlassFish v3 refcardz. He is one of the founder members of NetBeans Dream Team and a GlassFish community spotlighted developer. Recently Masoud's new book, GlassFish Security has been published which covers GlassFish v3 security and Java EE 6 security.

Masoud's main area of research and interest includes service-oriented architecture and large scale systems' development and deployment and in his leisure time he enjoys photography, mountaineering and camping. Masoud's can be followed at his Twitter account.

Masoud has posted 82 posts at DZone. You can read more from them at their website. View Full User Profile

Introducing NIO.2 (JSR 203) Part 6: Filtering Directory Content and Walking Over a File Tree

08.25.2010
| 5236 views |
  • submit to reddit

In this part we will look at how the directory tree walker and the directory stream reader works. These two features are another couple of long requested features which was not included in the core Java before Java 7.

First, lets see what directory stream reader is, this API allows us to filter content of a directory on the file system and extract the file names that matches our filter criteria. The feature works for very large folders with thousands of files.

For filtration we can use PathMatcher expression matching the file name or we can filter the directory content based on the different file attributes. for example based on the file permissions or the file size.

Following sample code shows how to use the DirectoryStream along with filtering. For using the PathMatcher expression we can just use another overload of the newDirectoryStream method which accepts the PathMatcher expression instead of the filter.

public class DirectoryStream2 {

public static void main(String args[]) throws IOException {
//Getting default file system and getting a path
FileSystem fs = FileSystems.getDefault();
Path p = fs.getPath("/usr/bin");

//creating a directory streamer filter
DirectoryStream.Filter
filter = new DirectoryStream.Filter
() {

public boolean accept(Path file) throws IOException {
long size = Attributes.readBasicFileAttributes(file).size();
String perm = PosixFilePermissions.toString(Attributes.readPosixFileAttributes(file).permissions());
if (size > 8192L && perm.equalsIgnoreCase("rwxr-xr-x")) {
return true;
}
return false;
}
};
// creating a directory streamer with the newly developed filter
DirectoryStream
ds = p.newDirectoryStream(filter);
Iterator
it = ds.iterator();
while (it.hasNext()) {

Path pp = it.next();

System.out.println(pp.getName());
}
}
}

The above code is self explaining and I will not explain it any further than the in-line comments.

Next subject of this entry is directory tree walking or basically file visitor API. This API allows us to walk over a file system tree and execute any operation we need over the files we found. The good news is that we can scan down to any depth we require using the provided API.

With the directory tree walking API, the Java core allows us to register a vaster class with the directory tree walking API and then for each entry the API come across, either a file or a folder, it calls our visitor methods. So the first thing we need is a visitor to register it with the tree walker. Following snippet shows a simple visitor which only prints the file type using the Files.probeContentType() method.


class visit extends SimpleFileVisitor
{

@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
try {
System.out.println(Files.probeContentType(file));

} catch (IOException ex) {
Logger.getLogger(visit.class.getName()).log(Level.SEVERE, null, ex);
}
return super.visitFile(file, attrs);
}

@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
return super.postVisitDirectory(dir, exc);
}

@Override
public FileVisitResult preVisitDirectory(Path dir) {
return super.preVisitDirectory(dir);
}

@Override
public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
return super.preVisitDirectoryFailed(dir, exc);
}

@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
return super.visitFileFailed(file, exc);
}
}

As you can see we extended the SimpleFileVisitor and we have visitor methods for all possible cases.

Now that we have the visitor class, the rest of the code is straight forward. following sample shows how to walk over /home/masoud directory down to two levels.

public class FileVisitor {

public static void main(String args[]) {

FileSystem fs = FileSystems.getDefault();
Path p = fs.getPath("/home/masoud");
visit v = new visit();
Files.walkFileTree(p, EnumSet.allOf(FileVisitOption.class), 2, v);

}
}

You can grab the latest version of Java 7 aka Dolphin from here and from the same page you can grab the latest JavaDoc which is generated from the same source code that is used to generate the binary bits. Other entries of this series are under the NIO.2 tag of my weblog.

From http://kalali.me/introducing-nio-2-jsr-203-part-6-filtering-directory-content-and-walking-over-a-file-tree/

Published at DZone with permission of its author, Masoud Kalali.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags: