2015-11-06 10 views
5

Ich habe ein Verzeichnis mit 100.000 Dateien und ich muss sie alle durchlaufen, um einen Wert zu lesen. Im Moment benutze ich listFiles(), um alle Dateien in einem Array zu laden und dann nacheinander zu iterieren. Aber gibt es eine speichereffiziente Möglichkeit, dies zu tun, ohne in ein Array zu laden?Iterieren große Menge von Dateien in einem Verzeichnis

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

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

[Eine Antwort gab ich früher könnte helfen] (http://stackoverflow.com/questions/27898652/how-to-read-multiple-text-files-in-java-for-gui-use-didnt-find-the-answer/27900034#27900034) Sie müssen einige Funktionen ändern, aber die Verwendung von Streams ist möglicherweise effizienter. Nicht sicher über die Leistung, obwohl. – easyDaMan

Antwort

6

Seit Java 7 können Sie mithilfe des Datei-Besuchermusters den Inhalt eines Verzeichnisses rekursiv aufrufen.

Die Dokumentation für die Schnittstelle FileVisitor lautet here.

Dies ermöglicht es Ihnen, über Dateien zu iterieren, ohne ein großes Array von File-Objekten zu erstellen.

Einfaches Beispiel, Dateinamen auszudrucken:

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; 
     } 
    } 
}); 
+0

Danke! das war genau das, was ich gesucht habe :) – prem89

+0

@ prem89 du bist willkommen! – Mena

1

Wenn Sie die übermäßigen vorformulierten vermeiden wollen, die mit JDK kommen FileVisitor, können Sie Guava verwenden. Files.fileTreeTraverser() gibt Ihnen eine TreeTraverser<File>, die Sie zum Überqueren Sie die Dateien im Ordner (oder auch Unterordner) verwenden können:

for (File f : Files.fileTreeTraverser() 
        .preOrderTraversal(new File("/parent/folder"))) { 
    // do something with each file 
} 
+0

Dies ruft intern 'Collections.unmodiableList (Arrays.asList (dateien));' auf, d. H. Ich denke nicht, dass dies besser ist als der Code aus der Frage selbst. – jan

+0

@jan, hängt davon ab, was Sie mit "besser" meinen. Ich mag Guavas "TreeTraverser", weil es eine wirklich starke Abstraktion ist, die es ermöglicht, Ihr Ding prägnant und lesbar zu machen, wodurch weniger Platz für Bugs bleibt. Ja, es ist vielleicht nicht die performanteste Lösung, aber in den meisten Fällen ist dies wahrscheinlich nicht der Flaschenhals der Anwendung. Dies kann auch im Fall von OP mit 100k-Dateien gelten. Ich würde zuerst die einfachste mögliche Lösung verwenden und nur für die Leistung optimieren, wenn die einfachste mögliche Lösung nicht gut genug ist. –

+0

Unter anderen Umständen würde ich voll und ganz zustimmen, aber als Antwort/Kommentar in dieser Frage bezüglich einer effizienten Lösung kann ich nicht zustimmen. Und vielleicht gibt es noch mehr Dateien als 100k. – jan

2

Java 8 lazily geladen Stream Version:

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