有没有比递归更好的文件搜索算法?

时间:2017-04-05 16:28:40

标签: java algorithm file recursion file-search

我使用递归来搜索特定类型的文件(例如,此处使用.pdf文件)。 我的递归算法搜索所有子文件夹。 但是我发现当子文件夹太多时它缺乏性能。子子文件夹,子子文件夹。 我想知道是否有更好的文件搜索算法。

下面是我的文件搜索递归代码。我以.pdf文件为例

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){    
        }
    }
}

与文件资源管理器中的搜索选项相比,此代码更快或更等。我想知道比这更快的算法

4 个答案:

答案 0 :(得分:2)

线程问题是启动它们会产生成本,因此文件浏览+递归的增加必须比N个文件夹/线程的额外成本更好。

这是一个使用循环的简单方法(经典的递归替换)

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

测量两种方法并选择更快的选项

答案 1 :(得分:2)

尝试迭代方式

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){    
  }
}

答案 2 :(得分:1)

Probaply你可以使用多线程...

你输入的每个文件夹,你从新线程开始......即使你有比你的CPU更多的线程,它也不是问题,因为Windows可以运行更多的线程......

答案 3 :(得分:1)

使用Files.walk()方法返回Java8 Stream。您可以使用并行流非常轻松地并行化该计算。

在try with resources方法中使用以下方便的习惯用法:

尝试(Stream vals = Files.walk(rootPath)){ ....}

在rootPath中,您可以使用Paths.get(“root location”)实际到达根位置。