1. Übersicht
In diesem Tutorial wird zeigen, wie große Dateien in Java effizient lesen können. Java - kehren Sie zu den Grundlagen zurück.
2. In Erinnerung lesen
Die Standardmethode zum Lesen von Dateizeilen besteht darin, im Speicher zu lesen. Sowohl Guava als auch ApacheCommonsio bieten Methoden zum schnellen Lesen von Dateizeilen wie folgt:
Files.readLines(new File(path), Charsets.UTF_8);
FileUtils.readLines(new File(path));
Das Problem bei dieser Methode besteht darin, dass alle Zeilen der Datei im Speicher gespeichert sind. Wenn die Datei groß genug ist, wird das Programm schnell eine Ausnahme von MemoryError ausgelöst.
Zum Beispiel: Lesen Sie eine Datei von ca. 1G:
@Testpublic void GiftUSEGuava_WeniteratingAfile_ThenWorks () löst IOException {String path = ... files.readlines (neue Datei (Pfad), charsets.utf_8);} ausDiese Methode nimmt zu Beginn nur eine kleine Menge Speicher ein: (sie verbraucht etwa 0 MB Speicher)
[Main] Info org.baeldung.java.corejavaiounittest - Gesamtspeicher: 128 MB [Main] Info org.baeldung.java.corejavaiounittest - Freier Speicher: 116 MB
Wenn jedoch alle Dateien in den Speicher gelesen werden, können wir endlich sehen (ca. 2 GB Speicher wird verbraucht):
[Main] Info org.baeldung.java.corejavaiounittest - Gesamtspeicher: 2666 MB [Haupt] Info org.baeldung.java.corejavaiounittest - Kostenloser Speicher: 490 MB
Dies bedeutet, dass dieser Prozess etwa 2,1 GB Speicher verbraucht - der Grund ist einfach: Jetzt werden alle Zeilen der Datei im Speicher gespeichert.
Wenn Sie den gesamten Inhalt einer Datei in den Speicher in den Speicher in den Speicher ausführen, ist dies offensichtlich, wie groß der tatsächliche verfügbare Speicher ist.
Außerdem müssen wir normalerweise nicht alle Zeilen der Datei gleichzeitig in den Speicher einfügen - stattdessen müssen wir nur jede Zeile der Datei durchqueren, dann die entsprechende Verarbeitung durchführen und nach der Verarbeitung wegwerfen. Genau das werden wir tun - durch Reihen durchzusetzen, anstatt alle Zeilen in Erinnerung zu nehmen.
3. Dateistrom
Schauen wir uns nun diese Lösung an - wir werden die Klasse java.util.scanner verwenden, um den Inhalt der Datei zu scannen und sie kontinuierlich für Zeile zu lesen:
FileInputStream inputStream = null; scanner sc = null; try {inputStream = new FileInputStream (Pfad); SC = neuer Scanner (InputStream, "UTF-8"); while (sc.hasnextline ()) {String line = sc.Nextline (); // system.out.println (Linie); } // Beachten Sie, dass Scanner Ausnahmen unterdrückt, wenn (sc.ioException ()! = null) {throw sc.ioException (); }} schließlich {if (inputStream! = null) {inputStream.close (); } if (sc! = null) {sc.close (); }}Diese Lösung durchquert alle Zeilen in der Datei - so dass jede Zeile verarbeitet werden kann, ohne darauf zu verweisen. Wie auch immer, sie wurden nicht im Gedächtnis gespeichert: (ca. 150 MB Speicher wurde verbraucht)
[Main] infoorg.baeldung.java.corejavaiounittest-totalMemory: 763MB
[Main] Infoorg.Baeldung.java.Corejavaiounittest-Freememory: 605 MB
4. Apachecommonsio Stream
Sie können auch die Commonsio -Bibliothek verwenden, um sie mit dem von der Bibliothek bereitgestellten benutzerdefinierten Linesiterator zu implementieren:
Linesiterator it = FileUtils.lineIterator (theFile, "utf-8"); try {while (it.hasNext ()) {String line = it.nextline (); // etwas mit Zeile}} endlich {linesiterator.closequiet (It);}Da die gesamte Datei nicht im Speicher gespeichert ist, führt dies zu einem eher konservativen Speicherverbrauch: (ca. 150 MB Speicher wird verbraucht)
[Main] Infoo.B.Java.CorejavaioIneInegationstest-TotalMemory: 752MB
[Main] Infoo.B.Java.CorejavaioIneInegationstest-Freememory: 564MB
5. Schlussfolgerung
In diesem kurzen Artikel wird beschrieben, wie große Dateien ohne wiederholtes Lesen verarbeitet und der Speicher ausgelaufen ist. Dies bietet eine nützliche Lösung für die Verarbeitung großer Dateien.
Alle diese Beispiele werden implementiert und Code -Snippets für mein GitHub -Projekt verfügbar. Dies ist ein Eclipse -basiertes Projekt, daher sollte es einfach importiert und ausgeführt werden.
Das obige ist der gesamte Inhalt dieses Artikels über Java effizientes Lesen großer Dateien. Ich hoffe, es wird für alle hilfreich sein. Interessierte Freunde können weiterhin auf andere verwandte Themen auf dieser Website verweisen. Wenn es Mängel gibt, hinterlassen Sie bitte eine Nachricht, um darauf hinzuweisen. Vielen Dank an Freunde für Ihre Unterstützung für diese Seite!