我有一個包含100,000個文件的目錄,我需要遍歷它們以讀取值。現在我使用listFiles()
加載數組中的所有文件,然後逐個迭代。但有沒有一種高效的內存方式來做到這一點,而不需要加載數組?在目錄中迭代大文件集
File[] tFiles = new File(Dir).listFiles();
try {
for (final File tFile : tFiles) {
//Process files one by one
}
}
我有一個包含100,000個文件的目錄,我需要遍歷它們以讀取值。現在我使用listFiles()
加載數組中的所有文件,然後逐個迭代。但有沒有一種高效的內存方式來做到這一點,而不需要加載數組?在目錄中迭代大文件集
File[] tFiles = new File(Dir).listFiles();
try {
for (final File tFile : tFiles) {
//Process files one by one
}
}
從Java 7開始,您可以使用文件訪問者模式以遞歸方式訪問目錄的內容。
FileVisitor
接口的文檔是here。
這允許您迭代文件而不創建大量的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;
}
}
});
如果你想避免附帶JDK的FileVisitor
過度樣板,您可以使用Guava。 Files.fileTreeTraverser()
給你一個TreeTraverser<File>
,您可以使用該文件夾中遍歷文件(甚至是子文件夾):
for (File f : Files.fileTreeTraverser()
.preOrderTraversal(new File("/parent/folder"))) {
// do something with each file
}
這在內部調用'Collections.unmodifiableList(Arrays.asList(files));',即我認爲這不如問題本身的代碼更好。 – jan
@jan,取決於你的意思是「更好」。我喜歡Guava的'TreeTraverser',因爲它是一個非常強大的抽象概念,它可以簡潔明瞭地完成你的事情,從而爲蟲子留下更少的空間。是的,它可能不是最高性能的解決方案,但在大多數情況下,這可能不是應用程序的瓶頸。即使在OP有10萬個文件的情況下,這也可能成立。如果最簡單的解決方案不夠好,我會首先使用最簡單的解決方案,並僅針對性能進行優化。 –
在其他情況下,我完全同意,但作爲有關解決方案的回答/評論,我不能同意。而且可能有更多的文件爲100k。 – jan
的Java 8延遲加載流版本:
Files.list(new File("path to directory").toPath()).forEach(path -> {
File file = path.toFile();
//process your file
});
[的回答我剛纔給可能有幫助](http://stackoverflow.com/questions/27898652/how-to-read-multiple-text-files-in-java-for-gui-use-didnt-find-the-answer/27900034#27900034) 你必須改變一些功能,但使用流可能更有效。雖然不確定的表現。 – easyDaMan