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

Is there any better file search algorithm than recursion?

我使用递归来搜索特定类型的文件(例如,此处使用的是 .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){    
        }
    }
}

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

也许你可以使用多线程...

您输入的每个文件夹都会从新线程开始...即使您的线程数比 CPU 多,这也不是问题,因为 Windows 可以 运行 多更多话题...

线程的问题在于启动它们是有成本的,因此文件浏览+递归的增加必须优于 N folders/threads 的额外成本。

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

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

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

尝试迭代方式

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

使用 Files.walk() 方法 returns 一个 Java8 流。您可以使用并行流很容易地并行化该计算。

在尝试使用资源方法中使用以下方便的习惯用法:

try(流值 = Files.walk(rootPath)){ ....}

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