更快地获取大型目录内容(java.io.File 个备选方案)

Get large directory content faster (java.io.File alternatives)

我已经使用旧的、过时的 java.io.File.listFiles() 太久了。

表现不太好。它是:

有哪些选择?

Java 7 的 java.nio.file 包可用于增强性能。

迭代器

DirectoryStream<T> 接口可用于循环访问目录,而无需将其内容预加载到内存中。 旧的 API 创建文件夹中所有文件名的数组,而新方法在迭代过程中遇到每个文件名(或有限大小的缓存文件名组)时加载它。

要获取表示给定 Path, the 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, starting with Java 8 you could implement it with a lambda expression, overriding the Filter<T>.accept(T) method which decides if the given directory entry should be accepted or filtered. Then you would use the 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
}