递归文件搜索

时间:2012-05-14 18:50:12

标签: android

我正在尝试在根目录中查找文件及其子目录。

步骤1 - 在指定路径中查找目录。 步骤2-如果找到上述目录,请在其子目录中查找文件。

为此,我使用下面的递归搜索的代码片段。现在,问题是,当它满足上述两个要求时,如何突破递归??

 boolean bFileFound = false;
File  fileFound     = null;

private void findFile( File aFile, String sDir ){

    String  filePath = aFile.getAbsolutePath();

    if( aFile.isFile() && filePath.contains( sDir ) ){

              if( aFile.getName().contains( "test2.adv")){
                  Log.d(TAG, "[FILE] " + aFile.getName() );
                  fileFound = aFile;
                  bFileFound = true;
              }

             // return true;
    }else if( aFile.isDirectory() ){

        String sDirName = aFile.getName();
        Log.d(TAG, "[DIR] " + sDirName );

        if( sDirName.contains( sDir ) ){

            Log.d( TAG, "Found the directory..& Absolute Path = " + aFile.getAbsolutePath());
            sDir = sDirName;
        }

        File[] listFiles = aFile.listFiles();

        if( listFiles != null ){

          for( int i = 0; i < listFiles.length; i++ ){

              if(bFileFound)
                    return;

            findFile( listFiles[ i ], sDir );
          }
        }else{

          Log.d( TAG,  " [ACCESS DENIED]" );
        }
    }

   // return null;
}

谢谢, DK

2 个答案:

答案 0 :(得分:6)

/**
 * Search file a file in a directory. Please comment more here, your method is not that standard.
 * @param file the file / folder where to look our file for.
 * @param sDir a directory that must be in the path of the file to find
 * @param toFind the name of file we are looking for. 
 * @return the file we were looking for. Null if no such file could be found.
 */
private File findFile( File aFile, String sDir, String toFind ){
    if( aFile.isFile() && 
            aFile.getAbsolutePath().contains( sDir ) && 
            aFile.getName().contains( toFind ) ) {
                        return aFile;
        } else if( aFile.isDirectory() ) {
        for( File child : aFile.listFiles() ){
            File found = findFile( child, sDir, toFind );
                    if( found != null ) { 
                        return found;
                    }//if
        }//for
    }//else
   return null;
}//met

现在,在调用findFile时,将“test2.adv”作为第三个参数传递。这比硬编码更有趣。

另请注意,多个文件可能与您的搜索匹配,此功能无法很好地处理,它将返回找到的第一个。

答案 1 :(得分:0)

我采用了一种稍微不同的方法来解决这个问题,使用FileFilter和一种不同的递归搜索方法。在我的情况下,正在查找任何带有“.json”扩展名的文件,其中filename的大小写无关紧要。

首先,创建一个FileFilter实现类来保存文件名并执行递归搜索

public extension WKInterfaceImage {

    public func setImageWithUrl(url:String, scale: CGFloat = 1.0) -> WKInterfaceImage? {

        URLSession.shared.dataTask(with: NSURL(string: url)! as URL) { data, response, error in
            if (data != nil && error == nil) {
                let image = UIImage(data: data!, scale: scale)

                DispatchQueue.main.async() {
                   self.setImage(image)
                }
        }
        }.resume()

    return self
}

然后,用法非常简单:

/**
 * A {@link FileFilter} implementation that checks recursively files of a
 * specified fileName or extension string
 */
public class FileExtensionFinder implements FileFilter {
    private final String fileName;
    private final List<File> foundFiles;

    /**
     * Constructor for FileExtensionFinder
     * @param fileName string of the filename or extension being searched for
     */
    public FileExtensionFinder(String fileName) {
        this.fileName = fileName;
        this.foundFiles = new ArrayList<>();
    }

    @Override
    public boolean accept(File pathname) {
        // accept anything that is a folder or matches the fileName string
        return pathname.isDirectory() || pathname.getName().toLowerCase().endsWith(fileName);
    }

    /**
     * Searches recursively for all files with the provided filename/extension string
     * @param filesArray an array of files (including folders) to iterate over
     */
    public List<File> findFiles(File... filesArray) {
        for (File file : filesArray) {
            if (file.isDirectory()) {
                findFiles(file.listFiles(this));
            } else if (file.getName().toLowerCase().endsWith(fileName)) {
                foundFiles.add(file);
            }
        }
        return foundFiles;
    }
}