Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Java: Recursive listFiles with filter (See related posts)

Java's File class provides listFiles for listing all files in a directory but this does not recurse into subdirectories. This implementation does with an optional filter:

NB: This uses Java5 features such as foreach loop and generics but these can be removed to work with Java4 (see comments)

public static File[] listFilesAsArray(
		File directory,
		FilenameFilter filter,
		boolean recurse)
{
	Collection<File> files = listFiles(directory,
			filter, recurse);
//Java4: Collection files = listFiles(directory, filter, recurse);
	
	File[] arr = new File[files.size()];
	return files.toArray(arr);
}

public static Collection<File> listFiles(
// Java4: public static Collection listFiles(
		File directory,
		FilenameFilter filter,
		boolean recurse)
{
	// List of files / directories
	Vector<File> files = new Vector<File>();
// Java4: Vector files = new Vector();
	
	// Get files / directories in the directory
	File[] entries = directory.listFiles();
	
	// Go over entries
	for (File entry : entries)
	{
// Java4: for (int f = 0; f < files.length; f++) {
// Java4: 	File entry = (File) files[f];

		// If there is no filter or the filter accepts the 
		// file / directory, add it to the list
		if (filter == null || filter.accept(directory, entry.getName()))
		{
			files.add(entry);
		}
		
		// If the file is a directory and the recurse flag
		// is set, recurse into the directory
		if (recurse && entry.isDirectory())
		{
			files.addAll(listFiles(entry, filter, recurse));
		}
	}
	
	// Return collection of files
	return files;		
}

Comments on this post

toeside posts on Nov 03, 2006 at 20:50
Nice piece of code! And thanks for the Java4 syntax... I'm working this snippet into some ZIP compression utilities. I'd thought it'd be useful to post the imports it uses:
import java.io.File;
import java.io.FilenameFilter;
import java.util.Collection;
import java.util.Vector;

Also, I found the syntax for the Java4 iteration over the entries in listFiles() should be:
for (int f = 0; f < entries.length; f++) {
  File entry = (File) entries[f];
}
thefonseca posts on Sep 10, 2007 at 12:55
Very nice!
I missed some mechanism to control the depth of the search (since recursive algorithms are expensive).

So I modified the snippet this way:

public static Collection<File> listFiles(File directory,
FilenameFilter filter, int recurse) { // recurse is the "depth count"

(.......)

// If the file is a directory and the recurse flag
// is set, recurse into the directory
if ((recurse > 0) && entry.isDirectory()) {
recurse--;
files.addAll(listFiles(entry, filter, recurse));
recurse++;
}
}

// Return collection of files
return files;
}

That's it!
TallPaul posts on Jul 04, 2008 at 20:11
I'm fairly new to Java, but I believe you could make even more modifications to the recursion level to allow optionally ALL directories to be explored by passing in a -1 and changing thefonseca's code as follows (I also checked for null entries as that seemed to bite me in the butt):

        if (entries != null) {
          for (File entry : entries)
	  {
		// If there is no filter or the filter accepts the 
		// file / directory, add it to the list
		if (filter == null || filter.accept(directory, entry.getName()))
		{
			files.add(entry);
		}
		
		// If the file is a directory and the recurse flag
		// is set, recurse into the directory
                // -1 == Always recurse
                // 0 would mean stop at this directory
                // Anything > = will continue recursion until 0 is hit.
		if ((recurse <= -1) || (recurse > 0 && entry.isDirectory()))
		{
                    recurse--; 
                    files.addAll(listFiles(entry, filter, recurse));
                    recurse++;
		}
	  }
        }


In addition, it might help other rookies to know how to call this code. In another class, I used (specifically):

      FilenameFilter filter = new FilenameFilter() { 
           public boolean accept(File dir, String name) { 
                return name.endsWith(".xyz"); 
            } 
      }; 
      File seedDir = new File("C:\\Java\\Ibm\\j-jena-examples\\ImportWordnet");
      FileRecurser fr = new FileRecurser();
      File[] allMatchingFiles = fr.listFilesAsArray(seedDir, filter, -1);
      for (File f : allMatchingFiles) {
          System.out.println(f.getName());
      }



I'm sure there is probably a cleaner way to call the method. I am looking forward to seeing what it is!
Paul

You need to create an account or log in to post comments to this site.


Click here to browse all 5147 code snippets

Related Posts