问题

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


#1 热门回答(174 赞)

你可以使用File#isDirectory()来测试给定文件(路径)是否是目录。如果这是true,那么你只需使用其File#listFiles()结果再次调用相同的方法。这叫做recursion

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

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

请注意,当树比JVM的堆栈更深时,这对StackOverflowError很敏感。你可能想要使用迭代方法或tail-recursion,但这是另一个主题;)


#2 热门回答(69 赞)

如果你使用的是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();
    }
  }

}

如果你使用的是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();
    }
  }

}

#3 热门回答(26 赞)

查看Apache Commons中的577999589类 - 具体iterateFiles

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


原文链接