Dealing with Directories and Directory Trees in Java 7.0

This article is based on The Well-Grounded Java Developer, to be published Summer-2011. It is being reproduced here by permission from Manning Publications. Manning publishes MEAP (Manning Early Access Program,) eBooks and pBooks. MEAPs are sold exclusively through Manning.com. All pBook purchases include free PDF, mobi and epub. When mobile formats become available all customers will be contacted and upgraded. Visit Manning.com for more information. [ Use promotional code ‘java40beat’ and get 40% discount on eBooks and pBooks ]

also read:

Directory Trees in Java 7.0

Introduction

Welcome to J The ability to navigate directories has been given a major overhaul in Java 7. The addition of the new java.nio.file.DirectoryStreaminterface and its implementing classes allow you to perform the following broad functions:

  • Iterate over entries in a directory
  • Perform recursive move, copy, and delete operations via the walkFileTree method
  • Deal with large directory structures
  • Filter entries using regular expressions and MIME based content detection

We’ll explicitly cover the first two points1 (iterating over entries and walking the directory tree), starting with a simple example of iterating over a list of directory entries and filtering some out.

Iterating over a directory listing

First, we’ll cover the simple example of using a pattern matching filter to list all of the .java files in a project directory, as shown in listing 1.

Listing 1 Listing Java source code in a directory

 try
{
	Path dir = Paths.get("C:\workspace\java7developer\src"); #1
	DirectoryStream<Path> stream =
	dir.newDirectoryStream("*.java"); #2
	for (Path entry: stream) #3
	{ #3
		System.out.println(entry.getName()); #3
	} #3
	}
	catch (IOException e)
	{
		e.printStackTrace();
	}

#1 Starting path
#2 Declares a filtering stream
#3 Lists each .java file

You start by declaring the familiar Paths.getPath(String path) call (#1). The key part comes with the creation of the new DirectoryStream(String patternMatch) (#2), which returns a filtered DirectoryStream. Lastly we show that we’ve only got the .java files by printing out each entry (#3).

The example above shows the power of the new API when dealing with a single directory. But, what if you need to recursively filter across multiple directories?

Walking the directory tree

Walking a directory tree is a new feature in Java 7 and you will need to know a number of interfaces and implementation details in order to use it to its full potential. The key method to use for walking the directory is:

 Files.walkFileTree(Path startingDir, FileVisitor<? super Path> visitor);

Providing the startingDir is easy enough but, in order to provide an implementation of the FileVisitor interface (e.g., provide the tricky looking FileVisitor<? super Path> visitor parameter) it gets a bit trickier as you need to implement at least five methods:

  • FileVisitResult preVisitDirectory(T dir)
  • FileVisitResult preVisitDirectoryFailed(T dir, IOException exc)
  • FileVisitResult visitFile(T file, BasicFileAttributes attrs)
  • FileVisitResult visitFileFailed(T file, IOException exc)
  • FileVisitResult postVisitDirectory(T dir, IOException exc)

Looks like a good deal of work right? Well it is but, luckily, the API designers have supplied a default implementation, the SimpleFileVisitor<T>. Carrying on from our previous example of listing .java source files in a directory listing, we now list .java source files from all of the directories that sit underneath C:\workspace\java7developer\src. Listing 2 demonstrates this use of the walkFileTree method.

Listing 2 Listing Java source code in subdirectories

 public class Find
	{
	public static void main(String[] args) throws IOException
	{
		Path startingDir =
		Paths.get("C:\workspace\java7developer\src"); #A
		Files.walkFileTree(startingDir, new FindJavaVisitor()); #1
	}
	private static class FindJavaVisitor
		extends SimpleFileVisitor<Path> #2
		{
			public FindJavaVisitor() {};
			public FileVisitResult
			visitFile(Path file, BasicFileAttributes attrs) #3
			{
			if ((file != null) && (attrs != null))
			{
				if (file.getName().toString().endsWith(".java"))
				{
					System.out.println(file.getName().toString());
				}
			}
		return FileVisitResult.CONTINUE;
	}
}
}

#A Starting directory
#1 Calls to walkTheTree
#2 Implementation of SimpleFileVisitor<Path>
#3 Overrides visitFile

We start by calling the Files.walkFileTree method (#1). The key point to take in here is that we’re passing in FindJavaVisitor, which extends SimpleFileVisitor (#2). In other words, we want SimpleFileVisitor to do most of the work for us, traversing the directories, and so on. The only code we have to write is when we override the visitFile(Path, BasicFileAttributes) method (#3), in which we write some simple Java to see if a file ends with .java and to echo it out to stdout if it does.

Other use cases could be to recursively move, copy, delete, or otherwise modify files. In most cases, you’ll only need to extend SimpleFileVisitor, but the flexibility is there in the API if you want to implement your own complete FileVisitor.

Summary

We talked about the specific support put in place in Java 7 for dealing with directories. Specifically, we discussed iterating over a directory listing and walking the directory tree.

Comments

comments

About Krishna Srinivasan

He is Founder and Chief Editor of JavaBeat. He has more than 8+ years of experience on developing Web applications. He writes about Spring, DOJO, JSF, Hibernate and many other emerging technologies in this blog.

Comments

  1. praveena says:

    really a nice article and great post
    way

Speak Your Mind

*