如何遍历Java中的目录中的文件?

Jam*_*mes 159 java

我需要获取目录中所有文件的列表,包括所有子目录中的文件.使用Java完成目录迭代的标准方法是什么?

Bal*_*usC 196

您可以File#isDirectory()用来测试给定文件(路径)是否是目录.如果是这样true,那么您只需再次使用其File#listFiles()结果调用相同的方法.这称为递归.

这是一个基本的启动示例.

public static void main(String... args) {
    File[] files = new File("C:/").listFiles();
    showFiles(files);
}

public static void showFiles(File[] files) {
    for (File file : files) {
        if (file.isDirectory()) {
            System.out.println("Directory: " + file.getName());
            showFiles(file.listFiles()); // Calls same method again.
        } else {
            System.out.println("File: " + file.getName());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,这StackOverflowError对于树比JVM的堆栈可以容纳的深度更敏感.您可能希望使用迭代方法或尾递归,但这是另一个主题;)

  • 取决于您的JVM的内存设置.但通常像几千.如果您认为您可能遇到过类似的目录,那么请不要使用递归. (9认同)
  • 当文件系统在调用`isDirectory`和`listFiles`之间发生变化时,如果`System.out.println`阻塞或者你真的不走运,可能会发生`NullPointerException.检查`listFiles`的输出是否为null将解决该竞争条件. (4认同)

msa*_*ord 78

如果您使用的是Java 1.7,则可以使用java.nio.file.Files.walkFileTree(...).

例如:

public class WalkFileTreeExample {

  public static void main(String[] args) {
    Path p = Paths.get("/usr");
    FileVisitor<Path> fv = new SimpleFileVisitor<Path>() {
      @Override
      public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
          throws IOException {
        System.out.println(file);
        return FileVisitResult.CONTINUE;
      }
    };

    try {
      Files.walkFileTree(p, fv);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

}
Run Code Online (Sandbox Code Playgroud)

如果您使用的是Java 8,则可以使用以下流接口java.nio.file.Files.walk(...):

public class WalkFileTreeExample {

  public static void main(String[] args) {
    try (Stream<Path> paths = Files.walk(Paths.get("/usr"))) {
      paths.forEach(System.out::println);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

}
Run Code Online (Sandbox Code Playgroud)

  • 当遍历新目录并执行函数时,流有没有办法放置检查点? (2认同)

Ben*_*n J 27

退房的文件实用程序在Apache的百科全书类-特别iterateFiles:

允许迭代给定目录(以及可选的子目录)中的文件.

  • 这个API不是真正的流媒体(如果你关心内存使用),它首先生成一个集合,然后只返回一个迭代器:return listFiles(directory,fileFilter,dirFilter).iterator(); (4认同)

小智 7

运用 org.apache.commons.io.FileUtils

File file = new File("F:/Lines");       
Collection<File> files = FileUtils.listFiles(file, null, true);     
for(File file2 : files){
    System.out.println(file2.getName());            
} 
Run Code Online (Sandbox Code Playgroud)

如果您不想要子目录中的文件,请使用false.


Wim*_*uwe 7

对于Java 7+,还有https://docs.oracle.com/javase/7/docs/api/java/nio/file/DirectoryStream.html

从Javadoc中获取的示例:

List<Path> listSourceFiles(Path dir) throws IOException {
   List<Path> result = new ArrayList<>();
   try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.{c,h,cpp,hpp,java}")) {
       for (Path entry: stream) {
           result.add(entry);
       }
   } catch (DirectoryIteratorException ex) {
       // I/O error encounted during the iteration, the cause is an IOException
       throw ex.getCause();
   }
   return result;
}
Run Code Online (Sandbox Code Playgroud)