如何遍历Java中目录中的文件?
您可以使用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代替,但这是另一个主题;)
这是一棵树,所以递归是你的朋友:从父目录开始,调用方法来获取一个子文件数组。遍历子数组。如果当前值是一个目录,则将其传递给您的方法的递归调用。如果不是,则适当地处理叶文件。
查核在Apache的百科全书的FileUtils类 - 特别iterateFiles:
允许对在给定的目录(和可选及其子目录)中的文件迭代。
这个API是不是真正流(如果你关心的内存使用),它首先生成一个集合,只有在它返回一个迭代: 回报listFiles(目录的FileFilter ,dirFilter).iterator(); – 2013-11-29 16:28:58
Java 1.6的不错选项。 – 2015-03-19 20:36:06
如果您使用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();
}
}
}
有没有一种方法可以让流在放置新目录时执行某个功能时放置检查点? – 2017-12-26 15:03:40
使用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());
}
使用虚假的,如果你不需要子目录中的文件。
对于Java 7+,也有从的Javadoc采取https://docs.oracle.com/javase/7/docs/api/java/nio/file/DirectoryStream.html
例子:
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;
}
要与@msandiford答案添加,因为大多数时候,当一个文件树走U可以想要执行一个函数作为一个目录或任何特定的文件被访问。如果你不愿意使用流。覆盖下面的方法可以实现
Files.walkFileTree(Paths.get(Krawl.INDEXPATH), EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
throws IOException {
// Do someting before directory visit
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
// Do something when a file is visited
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc)
throws IOException {
// Do Something after directory visit
return FileVisitResult.CONTINUE;
}
});
非常感谢Balus,对于有多深可能是一般猜测的任何想法? – James 2010-07-01 02:56:05
取决于您的JVM的内存设置。但通常有几千像这样的东西。如果你认为你可能会碰到类似的目录,那么不要使用递归。 – 2010-07-01 04:06:50
当文件系统在调用'isDirectory'和'listFiles'时发生'NullPointerException',就像'System.out.println'块可能发生的情况一样,或者你真的很不幸。检查'listFiles'的输出是否为空将解决竞争条件。 – 2014-04-20 18:00:00