Recursively search a directory tree in Java
Description
The following code shows how to recursively search a directory tree.
Example
//from w w w .ja v a 2s . c om
/*
* Copyright 2007 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
/**
* Recursively search a directory tree, for each File found in it, call
* FileFinderListener.proceedFile. A filter can be set prior calling this
* method.
*
* @author ycoppel@google.com (Yohann Coppel)
*
*/
public class FileLister {
/**
* Base directory to explore.
*/
private File classPath;
/**
* File listener for callbacks.
*/
private FileListerListener listener;
/**
* @param classPath
* path to the classFile (usually top level package as com in
* com.google.common)
*/
public FileLister(File classPath, FileListerListener depmk) {
this.classPath = classPath;
this.listener = depmk;
}
/**
* begin the search of class files in the classPath given to the constructor.
*/
public void start() {
listener.startProcessing();
for (File f : classPath.listFiles()) {
dfsFileSearch(f);
}
listener.endOfProcessing();
}
/**
* operate a recursive depth first search in the directory. If file is a
* directory, recursively search into for files. For each file found, check if
* it passes the filter of DepMaker, and if yes, call proceedFile with the
* file.
*
* @param file
* File where to start the dfsFileSearch
*/
private void dfsFileSearch(File file) {
boolean dirMatches = listener.directoryFilter(file.getPath());
if (file.isDirectory()) {
// call callback for entering the directory only if the directory matches
if (dirMatches) {
listener.enterDirectory(file.getPath().replaceFirst(classPath.getPath(), ""));
}
// look inside of the directory anyway (maybe sub directories matches...
for (File f : file.listFiles()) {
dfsFileSearch(f);
}
// get out of the directory, callback.
if (dirMatches) {
listener.outDirectory(file.getPath().replaceFirst(classPath.getPath(), ""));
}
} else { // dir.isFile() == true
if (listener.fileFilter(file.getPath()) && dirMatches) {
try {
listener.proceedFile(new FileInputStream(file), file.getPath().replaceFirst(
classPath.getPath(), ""));
} catch (FileNotFoundException e) {
// should not happen, cause we just seen it on the hard drive...
// but who knows...
e.printStackTrace();
}
}
}
}
}
/*
* Copyright 2007 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
/**
* Listener for callbacks when directories and files are found when exploring a
* directory, or a jar file for example.
*
* @author ycoppel@google.com (Yohann Coppel)
*
*/
interface FileListerListener {
/**
* Filter to apply to (normal - i.e not a directory) files found in the
* directory. May be a simple filename check as "end with .class"
*
* @param name
* filename
* @return true if the filename pass the filter, and that proceedFile should
* be called on this file later
*
*/
public boolean fileFilter(String name);
/**
* Filter to apply to directories. If this methods return false,
* subdirectories should not be traversed. May be a simple directory path
* check as "start with 'directoryfilter'"
*
* @param name
* filename to check
* @return true if the directory can contain interresting files.
*/
public boolean directoryFilter(String name);
/**
* method called when a file passing the fileFilter test is found.
*
* @param f
* file found.
*/
public void proceedFile(InputStream f, String name);
/**
* called when entering in the given directory
*
* @param directoryPath
*/
public void enterDirectory(String directoryPath);
/**
* called when we step out from the given directory
*
* @param directoryPath
*/
public void outDirectory(String directoryPath);
/**
* callback called at the begining of the processing
*/
public void startProcessing();
/**
* callback called at the end of the processing
*/
public void endOfProcessing();
}