我用过旧的、过时的java.io.File.listFiles()
太久了。
性能不是很好。它是:
- 昂贵,因为它创建了一个新的
File
每个条目的对象。 - 慢,因为你必须等待数组完成才能开始处理。
- 非常糟糕,尤其是当您只需要处理部分内容时。
有哪些替代方案?
最佳答案
Java 7 java.nio.file
包可用于提高性能。
迭代器
DirectoryStream<T>
接口(interface)可用于迭代目录,而无需将其内容预加载到内存中。
旧 API 在文件夹中创建一个包含所有文件名的数组,而新方法在迭代过程中遇到每个文件名(或有限大小的缓存文件名组)时加载它。
获取表示给定 Path
的实例, Files.newDirectoryStream(Path)
可以调用静态方法。
我建议您使用 try-with-resources 语句来正确关闭流,但如果不能,请记住在最后使用 DirectoryStream<T>.close()
手动关闭流。 .
Path folder = Paths.get("...");
try (DirectoryStream<Path> stream = Files.newDirectoryStream(folder)) {
for (Path entry : stream) {
// Process the entry
}
} catch (IOException ex) {
// An I/O problem has occurred
}
过滤器
DirectoryStream.Filter<T>
接口(interface)可用于在迭代期间跳过条目组。
因为它是 @FunctionalInterface
,从 Java 8 开始,您可以使用 lambda 表达式实现它,覆盖 Filter<T>.accept(T)
决定是否应接受或过滤给定目录条目的方法。然后你会使用 Files.newDirectoryStream(Path, DirectoryStream.Filter<? super Path>)
静态方法与新创建的实例。
或者您可能更喜欢 Files.newDirectoryStream(Path, String)
静态方法,可用于简单的文件名匹配。
Path folder = Paths.get("...");
try (DirectoryStream<Path> stream = Files.newDirectoryStream(folder, "*.txt")) {
for (Path entry : stream) {
// The entry can only be a text file
}
} catch (IOException ex) {
// An I/O problem has occurred
}
Path folder = Paths.get("...");
try (DirectoryStream<Path> stream = Files.newDirectoryStream(folder,
entry -> Files.isDirectory(entry))) {
for (Path entry : stream) {
// The entry can only be a directory
}
} catch (IOException ex) {
// An I/O problem has occurred
}
关于java - 更快地获取大目录内容(java.io.File 替代品),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31706058/