codersnet
codersnet

Reputation: 145

File search recursively

I am trying to find a file in a root directory and it's sub-directories.

Step1- Find a directory in a specified path. Step2- If the above directory is found, look for a file in one of it's sub-directory.

For this, I use the below code snippet that search recursively.. Now, the issue here is, how do I break out of the recursion when it meets both of my above requirements..?

 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;
}

Thanks, DK

Upvotes: 6

Views: 3930

Answers (2)

petey
petey

Reputation: 17170

I took a slightly different approach to solve this issue using a FileFilter and a different method for searching recursively. In my case was looking for any file with a ".json" extension where filename case did not matter.

First, create a FileFilter implementation class to hold the file name and perform the recursive search

/**
 * 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;
    }
}

Then, usage is fairly simple:

File fileLocation = // get your file here ...
List<File> foundFiles = new FileExtensionFinder(".json").findFiles(fileLocation);

Upvotes: 0

Snicolas
Snicolas

Reputation: 38168

/**
 * 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

Now, pass "test2.adv" as third param when you invoke findFile. That's more interesting than hardcoding it.

Also please note that multiple files could match your search, this function doesn't handle it well, it will return the first one found.

Upvotes: 7

Related Questions