2

In my android app I need to find if a file of a certain format exists in the directory. I wrote the code and it works well but if the directory has too many directories each of which has many files and directories it becomes a bit slow.

Note: I am also calculating total txt files in the directory

This is my code

int count = 0;

private boolean containsTXT(File file) {
        boolean result = false;
        String fList[] = file.list();

        if (fList == null)
            return false;
        else {
            for (int i = 0; i < fList.length; i++) {
                File file = new File(file, fList[i]);
                if (file.isFile() && (file.getName().endsWith("txt"))) {
                    result = true;
                    count++;   // This counts total txt files in the dir
                } else if (file.isDirectory()) {
                    result = containsTXT(file);
                }
            }
        }
        return result;
    }

I am basically following the most general approach but there are apps which do the same job that i am trying to do in my app and are faster. Does anybody know of a better approach or algorithm for this task? Thanks !!

varunkr
  • 5,364
  • 11
  • 50
  • 99

4 Answers4

2

You can use apache commons io library. Specifically the FileUtils.listFiles static method

Collection<File> allTxtFiles = FileUtils.listFiles(folder, new String[]{"txt"}, true)
int count = allTxtFiles.size();

Not sure if it will be faster, but it is generally good practice to use very popular open source libraries instead of reinventing the wheel because:

  1. you shouldn't spend time developing existing functionality,
  2. they most probably don't have bugs because have been used by a lot of people for long time,
  3. they were reviewed by lots of experienced programmers and most probably are very efficient and use fast algorithms and such,
  4. They are more readable by other developers and by you later on.

Just try it out and see if it works for you.

Yashash Gaurav
  • 581
  • 5
  • 9
Arsen Simonean
  • 362
  • 2
  • 17
1

Here's your code slightly modified to use short-circuit evaluation:

private boolean containsTXT(File file) {
    String fList[] = file.list();

    if (fList == null)
        return false;
    for (int i = 0; i < fList.length; i++) {
        File file = new File(file, fList[i]);
        if (file.isFile() && (file.getName().endsWith("txt")))
            return true;
        if (file.isDirectory() && containsTXT(file))
            return true;
    }
    return false;
}
Brent Washburne
  • 12,904
  • 4
  • 60
  • 82
  • Thanks, though this is an optimization but my need is more than that. Will the iterative approach be faster? – varunkr Apr 28 '16 at 17:38
1

You can use FileUtils from Apache Commons I/O to recursively search directories and get filenames ending with .txt. An example is given in this comment.

List all files from a directory recursively with Java

Community
  • 1
  • 1
Sandeep M
  • 11
  • 2
0

You can make it iterative instead of recursive by holding the files encountered during traversal in a FIFO kind of list.

Add to the end of the list all files in the currently traversed directory. Remove from the head the file currently being traversed.

private boolean containsTXT(File rootPath) {
    boolean result = false;

    LinkedList<File> fileFIFO = new LinkedList<>();

    fileFIFO.add(rootPath); //Add root path to the fifo list

    //Traverse the FIFO linkedlist until it's empty
    while(!fileFIFO.isEmpty()){
        File file = fileFIFO.poll(); //Retrieve item from the head

        System.out.println(file.getAbsolutePath()+"\n");

        if(file.isDirectory()){ //If retrieved item from fifo list is a directory
            File[] filesInDir = file.listFiles();

            if(filesInDir != null){
                fileFIFO.addAll(Arrays.asList(file.listFiles())); //Add all files in directory to fifo
            }
        }else if(file.isFile() && (file.getName().endsWith("txt"))){
            result = true;
            break;
        }
    }

    System.out.println("ContainsTXT: "+result);
    return result;
}

The reason for using a FIFO kind of list is so that the traversal into sub-directories is ordered in a way we want.

Siddharth
  • 396
  • 2
  • 14