Java 迭代目录中的大型文件集
我有一个包含100000个文件的目录,我需要迭代它们来读取一个值。现在我使用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以来,您可以使用文件访问
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
});