更快地获取大型目录内容(java.io.File替代品)
我已经使用旧的,过时的java.io.File.listFiles()
太久了。
表现不太好。 它是:
- 昂贵,因为它为每个条目创建一个新的
File
对象。 - 慢,因为在开始处理之前必须等待数组完成。
- 非常糟糕,特别是如果您只需要处理内容的子集。
有哪些替代方案?
Java 7的java.nio.file
包可用于增强性能。
迭代器
DirectoryStream
接口可用于迭代目录而无需将其内容预加载到内存中。 虽然旧API在文件夹中创建了所有文件名的数组,但新方法在迭代期间遇到它时会加载每个文件名(或有限大小的缓存文件名组)。
要获取表示给定Path
的实例,可以调用Files.newDirectoryStream(Path)
静态方法。 我建议您使用try-with-resources语句来正确关闭流,但如果不能,请记住最后使用DirectoryStream
手动完成。
Path folder = Paths.get("..."); try (DirectoryStream stream = Files.newDirectoryStream(folder)) { for (Path entry : stream) { // Process the entry } } catch (IOException ex) { // An I/O problem has occurred }
filter
DirectoryStream.Filter
接口可用于在迭代期间跳过条目组。
由于它是@FunctionalInterface
,从Java 8开始,您可以使用lambda表达式实现它,覆盖Filter
方法,该方法决定是应该接受还是过滤给定的目录条目。 然后,您将使用新创建的实例的Files.newDirectoryStream(Path, DirectoryStream.Filter super Path>)
静态方法。 或者您可能更喜欢Files.newDirectoryStream(Path, String)
静态方法,它可以用于简单的文件名匹配。
Path folder = Paths.get("..."); try (DirectoryStream 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 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 }