Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 迭代目录中的大型文件集_Java_File_Nio - Fatal编程技术网

Java 迭代目录中的大型文件集

Java 迭代目录中的大型文件集,java,file,nio,Java,File,Nio,我有一个包含100000个文件的目录,我需要迭代它们来读取一个值。现在我使用listFiles()加载数组中的所有文件,然后逐个迭代。但是,有没有一种内存有效的方法可以在不加载数组的情况下执行此操作 File[] tFiles = new File(Dir).listFiles(); try { for (final File tFile : tFiles) { //Process files one by one } } 自Java7以来,您可以使用文件访问

我有一个包含100000个文件的目录,我需要迭代它们来读取一个值。现在我使用
listFiles()
加载数组中的所有文件,然后逐个迭代。但是,有没有一种内存有效的方法可以在不加载数组的情况下执行此操作

File[] tFiles = new File(Dir).listFiles();

try {
    for (final File tFile : tFiles) {
        //Process files one by one
    }
}

自Java7以来,您可以使用文件访问者模式递归地访问目录的内容

FileVisitor
界面的文档如下所示

这允许您在不创建大量
File
对象的情况下迭代文件

打印文件名的简单示例:

Path start = Paths.get(new URI("file:///my/folder/"));

Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
     @Override
     public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 
        throws IOException
     {
         System.out.println(file);
         return FileVisitResult.CONTINUE;
     }
     @Override
     public FileVisitResult postVisitDirectory(Path dir, IOException e)
        throws IOException
     {
         if (e == null) {
             System.out.println(dir);
             return FileVisitResult.CONTINUE;
         } 
         else {
             // directory iteration failed
             throw e;
         }
     }
 });
Path start=Path.get(新URI(“file:///my/folder/"));
walkFileTree(开始,新的SimpleFileVisitor(){
@凌驾
公共文件VisitResult visitFile(路径文件,基本文件属性属性属性)
抛出IOException
{
System.out.println(文件);
返回FileVisitResult.CONTINUE;
}
@凌驾
公共文件VisitResult postVisitDirectory(路径目录,IOE异常)
抛出IOException
{
如果(e==null){
系统输出打印项次(dir);
返回FileVisitResult.CONTINUE;
} 
否则{
//目录迭代失败
投掷e;
}
}
});

如果您想避免JDK的
文件访问者附带的过多样板文件,您可以使用。为您提供可用于遍历文件夹(甚至子文件夹)中的文件的路径:


Java 8延迟加载的流版本:

Files.list(new File("path to directory").toPath()).forEach(path -> {
    File file = path.toFile();
    //process your file
});

您必须更改某些功能,但使用流可能更有效。不过,我对表演不太确定。谢谢!这正是我想要的:)它在内部调用
Collections.unmodifiableList(Arrays.asList(files)),也就是说,我不认为这更好,因为问题本身的代码。@jan,取决于你所说的“更好”是什么意思。我喜欢Guava的
TreeTraverser
,因为它是一个非常强大的抽象,可以简洁易懂地完成您的工作,为bug留下更少的空间。是的,它可能不是性能最好的解决方案,但在大多数情况下,这可能不是瓶颈​ 应用程序的名称。即使在OP的100k文件的情况下,这也可能成立。我会首先使用最简单的解决方案,只有在最简单的解决方案不够好的情况下才对性能进行优化。在其他情况下,我完全同意,但作为关于有效解决方案的回答/评论,我不能同意。而且可能会有更多的文件,比如100k。我同意jan的观点——这是关于如何使其在文件数量方面具有可伸缩性。您的解决方案与引擎盖下的listFiles()相同。这将泄漏文件描述符。根据API文档,您需要在之后关闭流。最好使用
try(streamfiles=files.list(path.get(“path to dir”)){files.forEach(…);}
Files.list(new File("path to directory").toPath()).forEach(path -> {
    File file = path.toFile();
    //process your file
});