更快地获取大型目录内容(java.io.File 替代项)
2022-09-03 04:59:21
我已经使用旧的,过时的java.io.File.listFiles()
太久了。
性能不太好。是的:
- 成本高昂,因为它为每个条目创建一个新的
File
对象。 - 速度很慢,因为您必须等待数组完成才能开始处理。
- 非常糟糕,特别是如果你只需要处理内容的子集。
有哪些替代方案?
我已经使用旧的,过时的java.io.File.listFiles()
太久了。
性能不太好。是的:
File
对象。有哪些替代方案?
Java 7的java.nio.file
包可以用来增强性能。
目录流<T>
接口可用于循环访问目录,而无需将其内容预加载到内存中。虽然旧 API 在文件夹中创建一个包含所有文件名的数组,但新方法会在迭代期间遇到每个文件名(或有限大小的缓存文件名组)时加载它。
若要获取表示给定路径
的实例,可以调用 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>
接口可用于在迭代期间跳过条目组。
由于它是一个@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
}