【问题标题】:list all files from directories and subdirectories in Java列出Java中目录和子目录中的所有文件
【发布时间】:2011-03-01 18:50:27
【问题描述】:

列出 1000 多个目录和子目录中文件名的最快方法是什么?

编辑; 我当前使用的代码是:

import java.io.File;

public class DirectoryReader {

  static int spc_count=-1;

  static void Process(File aFile) {
    spc_count++;
    String spcs = "";
    for (int i = 0; i < spc_count; i++)
      spcs += " ";
    if(aFile.isFile())
      System.out.println(spcs + "[FILE] " + aFile.getName());
    else if (aFile.isDirectory()) {
      System.out.println(spcs + "[DIR] " + aFile.getName());
      File[] listOfFiles = aFile.listFiles();
      if(listOfFiles!=null) {
        for (int i = 0; i < listOfFiles.length; i++)
          Process(listOfFiles[i]);
      } else {
        System.out.println(spcs + " [ACCESS DENIED]");
      }
    }
    spc_count--;
  }

  public static void main(String[] args) {
    String nam = "D:/";
    File aFile = new File(nam);
    Process(aFile);
  }

}

【问题讨论】:

  • 最快是什么意思?代码最简单,在特定操作系统上性能最佳,还是在某些目录结构上性能最佳?
  • 就我而言;在 WinXP 上快速且尽可能简单。
  • 赞成,因为这是一个常见的用例,它确实帮助了我

标签: java directory


【解决方案1】:

这看起来不错(递归遍历目录)瓶颈将是您需要做的所有文件 i/o,优化您的 Java 不会显示任何真正的改进。

【讨论】:

    【解决方案2】:

    在 Java 7 引入新的 java.nio.file 类(如 DirectoryStream)之前,恐怕你已经拥有的将是最快的。

    【讨论】:

      【解决方案3】:

      唯一的改进是去掉static spc_count并将spcs字符串作为参数传递给Process。

      public static void main(String[] args) {
        String nam = "D:/";
        File aFile = new File(nam);
        Process("", aFile);
      }
      

      在进行递归调用时,做

      static void Process( String spcs, File aFile) {
        ...
        Process(spcs + " ", listOfFiles[i]);
        ...
      }
      

      这样你就可以从多个线程调用这个方法了。

      【讨论】:

      • 感谢@Alexander Pogrebnyak 的提示
      【解决方案4】:

      由于这个答案显示在谷歌之上,我正在添加一个 java 7 nio 解决方案来列出所有文件和目录,它在我的系统上花费的时间减少了大约 80%。

      try {
          Path startPath = Paths.get("c:/");
          Files.walkFileTree(startPath, new SimpleFileVisitor<Path>() {
              @Override
              public FileVisitResult preVisitDirectory(Path dir,
                      BasicFileAttributes attrs) {
                  System.out.println("Dir: " + dir.toString());
                  return FileVisitResult.CONTINUE;
              }
      
              @Override
              public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
                  System.out.println("File: " + file.toString());    
                  return FileVisitResult.CONTINUE;
              }
      
              @Override
              public FileVisitResult visitFileFailed(Path file, IOException e) {
                  return FileVisitResult.CONTINUE;
              }
          });
      } catch (IOException e) {
          e.printStackTrace();
      }
      

      【讨论】:

        【解决方案5】:

        如果您愿意使用第 3 方库,请查看 javaxt-core。它包括一个多线程递归目录搜索,应该比一次遍历一个目录更快。这里有一些例子:

        http://www.javaxt.com/javaxt-core/io/Directory/Recursive_Directory_Search

        【讨论】:

          【解决方案6】:

          我写了一个更简单的代码....试试这个...它将显示每个文件夹、子文件夹和文件...

           int Files=0,Directory=0,HiddenFiles=0,HiddenDirectory=0;
          
           public void listf(String directoryName){
          
          File file=new File(directoryName);
          
          File[] fileList=file.listFiles();
          
          if(fileList!=null){
          
          for(int i=0;i<fileList.length;i++){
          
          if(fileList[i].isHidden()){
          
          if(fileList[i].isFile())
          
          {
          
             System.out.println(fileList[i]);
          
          HiddenFiles++;
          
          }
          
          else{
          
            listf(String.valueOf(fileList[i]));
          
            HiddenDirectory++;
          
          }
          
          }
          
          else if (fileList[i].isFile()) {
          
          //System.out.println(fileList[i]);
          
          Files++;
          
          }
          
          else if(fileList[i].isDirectory()){
          
          Directory++;
          
          listf(String.valueOf(fileList[i]));
          
          }
          
          }
          
          }
          
          }
          
          
          
          public void Numbers(){
          
             System.out.println("Files: "+Files+" HiddenFiles: "+HiddenFiles+"Hidden Directories"+HiddenDirectory+" Directories: "+Directory);`
          
              }  
          

          【讨论】: