Heim  >  Artikel  >  Java  >  Java-Lösung für Speicherüberlauf beim Lesen großer Dateien

Java-Lösung für Speicherüberlauf beim Lesen großer Dateien

黄舟
黄舟Original
2017-08-10 09:21:332509Durchsuche

Der folgende Editor bringt Ihnen einen Artikel, der das Problem des Speicherüberlaufs beim Lesen großer Dateien in Java perfekt löst. Der Herausgeber findet es ziemlich gut, deshalb werde ich es jetzt mit Ihnen teilen und es allen als Referenz geben. Folgen wir dem Editor und werfen wir einen Blick darauf

1. Traditionelle Methode: Dateiinhalt im Speicher lesen

Standards zum Lesen von Dateizeilen Der Weg ist Zum Lesen im Speicher bieten sowohl Guava als auch Apache Commons IO eine Methode zum schnellen Lesen von Dateizeilen wie folgt:


Files.readLines(new File(path), Charsets.UTF_8); 
FileUtils.readLines(new File(path));

verwendet tatsächlich BufferedReader Oder seine Unterklasse LineNumberReader zum Lesen.

Das Problem beim herkömmlichen Ansatz: besteht darin, dass alle Zeilen der Datei im Speicher gespeichert werden. Wenn die Datei groß genug ist, wird das Programm bald ausgeführt um eine OutOfMemoryError-Ausnahme auszulösen.

Über das Problem nachdenken: Normalerweise müssen wir nicht alle Zeilen der Datei auf einmal im Speicher ablegen, sondern nur jede einzelne Zeile durchlaufen Zeile der Datei, und behandeln Sie sie dann entsprechend und werfen Sie sie weg, wenn Sie fertig sind. Wir können es also durch Zeileniteration lesen, anstatt alle Zeilen im Speicher abzulegen.

2. Methode zum Lesen großer Dateien

Ohne wiederholtes Lesen und ohne dass der Speicher knapp wird. Verarbeitung großer Dateien:

(1) Datei-Streaming-Methode: Verwenden Sie die Klasse java.util.Scanner, um den Inhalt der Datei zu scannen und kontinuierlich Zeile für Zeile zu lesen


FileInputStream inputStream = null; 
Scanner sc = null; 
try { 
 inputStream = new FileInputStream(path); 
 sc = new Scanner(inputStream, UTF-8); 
 while (sc.hasNextLine()) {
  String line = sc.nextLine(); 
  // System.out.println(line); 
  } 
}catch(IOException e){
  logger.error(e);
}finally {
  if (inputStream != null) { 
  inputStream.close(); 
  } 
  if (sc != null) {
    sc.close();
   }
}

Dieses Schema iteriert über alle Zeilen in der Datei, sodass jede Zeile verarbeitet werden kann, ohne einen Verweis darauf beizubehalten. Jedenfalls werden sie nicht im Speicher gespeichert!

(2) Apache Commons IO-Stream: implementiert unter Verwendung der Commons IO-Bibliothek unter Verwendung des benutzerdefinierten LineIterators, der von der Bibliothek bereitgestellt wird


LineIterator it = FileUtils.lineIterator(theFile, UTF-8); 
try {
 while (it.hasNext()) {
 String line = it.nextLine(); 
 // do something with line 
  } 
} finally {
 LineIterator.closeQuietly(it);
}

Da bei dieser Lösung nicht die gesamte Datei vollständig im Speicher abgelegt wird , führt dies auch zu einem recht konservativen Speicherverbrauch.

Das obige ist der detaillierte Inhalt vonJava-Lösung für Speicherüberlauf beim Lesen großer Dateien. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn