快速获取大型目录内容(java.io.File选项) [英] Get large directory content faster (java.io.File alternatives)

查看:159
本文介绍了快速获取大型目录内容(java.io.File选项)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用了旧的,过时的 java.io.File.listFiles() 时间太长。
$ b

不太好。这是:


  • 昂贵,因为它创建了一个新的 File 对于每个条目。

  • 缓慢,因为在开始处理之前必须等待数组完成。

  • 非常糟糕,特别是如果您只需要处理内容的子集时。 li>


有什么选择?

解决方案

Java 7的 java.nio.file 可以用来增强性能。



迭代器



DirectoryStream< 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){
//处理入口
}
发生I / O问题

code $ $ $ $ $ b

过滤器



DirectoryStream.Filter< T> 接口可用于在迭代期间跳过条目组。 >

既然是 @FunctionalInterface ,从Java 8开始,您可以使用lambda表达式实现它,覆盖 code> 方法决定是否给定直接应该接受或过滤tory项目。然后,您将使用 Files.newDirectoryStream(Path,DirectoryStream.Filter< ;? super path>) static method with新创建的实例。
或者您可能更喜欢 Files.newDirectoryStream(Path,String) 静态方法,可用于简单文件名匹配。

  Path folder = Paths.get(...); 
try(DirectoryStream< Path> stream = Files.newDirectoryStream(folder,* .txt)){
for(Path entry:stream){
//这个入口只能是一个文本文件

} catch(IOException ex){
//发生I / O问题
}






  Path folder = Paths.get(...); 
try(DirectoryStream< Path> stream = Files.newDirectoryStream(folder,
entry - > Files.isDirectory(entry))){
for(Path entry:stream){
//该条目只能是一个目录

catch(IOException ex ex){
//发生I / O问题
}


I've used the old, obsolete java.io.File.listFiles() for too long.

The performance is not so good. It is:

  • Expensive, since it creates a new File object for each entry.
  • Slow, because you have to wait for the array to be completed before starting the processing.
  • Very bad, especially if you need to work only on subset of the content.

What are the alternatives?

解决方案

The Java 7's java.nio.file package can be used to enhance performance.

Iterators

The DirectoryStream<T> interface can be used to iterate over a directory without preloading its content into memory. While the old API creates an array of all filenames in the folder, the new approach loads each filename (or limited size group of cached filenames) when it encounters it during iteration.

To get the instance representing a given Path, the Files.newDirectoryStream(Path) static method can be invoked. I suggest you to use the try-with-resources statement to properly close the stream, but if you can't, remember to do it manually at the end with 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
}

Filters

The DirectoryStream.Filter<T> interface can be used to skip groups of entries during iteration.

Since it's a @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>) static method with the newly created instance. Or you might prefer the Files.newDirectoryStream(Path, String) static method instead, which can be used for simple filename matching.

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.io.File选项)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆