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();

}




















Home »
  Java Tutorial »
    I/O »




Binary File
Byte Array
CharSet
Checksum
Console
Create Copy Move Delete
Directory
Drive
Encode Decode
File Attribute
File Lock
File System
GZIP
Jar File
NIO Buffer
Path
Scanner
StreamTokenizer
Temporary File
Text File
Zip