Kangkan Lahkar
Kangkan Lahkar

Reputation: 317

Is there any better file search algorithm than recursion?

I have used recursion to search for particular type of file (for example .pdf files is used here). My recursion algorithm searches for all subfolder. However I found that it lacks performance when there is too many sub-folder. sub-sub-folder, sub-sub-sub-folder. I want to know if there is better algorithm for file searching.

Below is my recursion code for file searching. I have used .pdf file as an example

import java.io.File;
public class FInd {
    public static void main(String[] args) {
        File f = new File("D:/");
        find(f);    
    }
    public static void find(File f){    
        File []list = f.listFiles();
        try{
            for(int i=0;i<list.length && list.length>0;i++){    
                if(list[i].isFile() && (list[i].getName().contains(".pdf")) ||
                        list[i].getName().contains(".PDF"))
                    System.out.println(list[i].getAbsolutePath());
                if(list[i].isDirectory()) find(list[i]);
            }
        }catch(Exception e){    
        }
    }
}

This code is somewhat faster or equal to when compared to search option in file explorer. I want to know any faster algorithm than this

Upvotes: 0

Views: 2375

Answers (4)

Abdou
Abdou

Reputation: 330

try the iterative way

public class Find {
public static void main(String[] args) {

  File f = new File("D:/");

  Stack stack = new Stack<File>();

  stack.push(f);

  while (!stack.empty())
  {    
      f = (File) stack.pop();
      File []list = f.listFiles();
      try{
          for(int i=0;i<list.length && list.length>0;i++){    
              if(list[i].isFile() && (list[i].getName().contains(".pdf")) ||
                      list[i].getName().contains(".PDF"))
                  System.out.println(list[i].getAbsolutePath());
              if(list[i].isDirectory()) stack.push(list[i]);
          }
      }catch(Exception e){    
  }
}

Upvotes: 2

Avneet Paul
Avneet Paul

Reputation: 303

Use the Files.walk() method which returns a Java8 Stream. You can parallelize that calculation quite easily by using a parallel stream.

Use the following convenient idiom in a try with resources method:

try(Stream vals = Files.walk(rootPath)){ .... }

In the rootPath, you could use Paths.get("root location") to actually get to the root location.

Upvotes: 1

bichito
bichito

Reputation: 1426

the problem with threading is that launching them has a cost, so the increase in file browsing + recursion has to be better than the additional cost of N folders/threads.

This is a simple method that uses a loop (the classical replacement for recursion)

static boolean avoidRecursion(String target){
    File currentDir = new File(System.getProperty("user.home"));
    Stack<File> dirs = new Stack<File>();
    dirs.push(currentDir);

    do{
        for(File f : dirs.pop().listFiles()){
            if (f.isDirectory())
                dirs.push(f);
            else{
                if (f.getName().equals(target))
                    return true;
            }
        }
    }while(!dirs.isEmpty());
    return false;
}

Measure both approaches and choose the option that is faster

Upvotes: 2

mirisbowring
mirisbowring

Reputation: 70

Probaply you could use multithreading...

Each folder you enter, you start at new thread... Even if you have more threads than your CPU, it ist not a Problem since Windows Can run much more threads...

Upvotes: 1

Related Questions