Schnellste Möglichkeit, Text-Datei Zeile für Zeile in Java zu lesen

7

Für die Protokollverarbeitung muss meine Anwendung zeilenweise Textdateien lesen. Zuerst habe ich die Funktion readLine () von BufferedReader benutzt, aber ich habe im Internet gelesen, dass BufferedReader beim Lesen von Dateien langsam ist.
Danach habe ich versucht, FileInputStream zusammen mit einem FileChannel und einem MappedByteBuffer zu verwenden, aber in diesem Fall gibt es keine ähnliche Funktion wie readLine (), also suche ich meinen Text nach einem Zeilenumbruch und verarbeite ihn:

%Vor%

Ich weiß, das ist wahrscheinlich kein guter Weg, es zu implementieren, aber wenn ich nur die Textdatei in Bytes lese, ist es 3 mal schneller als BufferedReader, aber Aufruf von new String(bytes) erzeugt einen neuen String und macht das Programm noch langsamer bei Verwendung eines BufferedReaders.
Also wollte ich fragen, wie man am schnellsten eine Textdatei Zeile für Zeile liest? Einige sagen BufferedReader ist die einzige Lösung für dieses Problem.

P.S .: ra ist eine Instanz von RunAutomaton aus der Bibliothek dk.brics.Automaton.

    
Yoni 27.04.2011, 06:39
quelle

5 Antworten

19

Ich bezweifle sehr, dass BufferedReader einen erheblichen Overhead verursachen wird. Das Hinzufügen eigenen Codes ist wahrscheinlich mindestens genauso ineffizient und möglicherweise auch falsch.

Zum Beispiel rufen Sie in dem Code, den Sie angegeben haben, new String(bytes) auf, was immer eine Zeichenfolge von 1024 Bytes erzeugt, wobei die Standardkodierung der Plattform verwendet wird ... keine gute Idee. Klar, du löschst das Array danach, aber deine Strings enthalten immer noch eine Menge '\ 0'-Zeichen - was viel Platz bedeutet, abgesehen von allem anderen. Sie sollten mindestens den Teil des Byte-Arrays einschränken, aus dem die Zeichenfolge erstellt wird (was auch bedeutet, dass Sie das Array danach nicht mehr löschen müssen).

Haben Sie wirklich versucht mit BufferedReader zu arbeiten und fanden es zu langsam? Sie sollten normalerweise den einfachsten Code schreiben, der zuerst Ihre Ziele erfüllt, und dann überprüfen, ob er schnell genug ist ... vor allem, wenn Ihr einziger Grund dafür eine unspezifizierte Ressource ist, die Sie "im Internet lesen". Willst du, dass ich Hunderte von Beispielen von Leuten finde, die falsche Vorschläge zur Leistungssteigerung herausbringen? :)

Alternativ können Sie sich die Guava Überlastung von Files.readLines() anzeigen lassen a LineProcessor .

    
Jon Skeet 27.04.2011, 06:48
quelle
2

Mit plain BufferedReader habe ich 100+ MB / s . Es ist sehr wahrscheinlich, dass die Geschwindigkeit, mit der Sie die Daten von der Festplatte lesen können, Ihr Flaschenhals ist. Daher macht es keinen großen Unterschied, wie Sie das Lesen durchführen.

BufferedReader ist nicht die einzige Lösung, aber es ist schnell genug für 99% der Anwendungsfälle, warum also die Dinge komplizierter machen als sie sein müssen?

    
Peter Lawrey 27.04.2011 06:55
quelle
1

Sind Rahmen eine Alternative?

Ich weiß nicht über die Leistung, aber

Ссылка

Ссылка Siehe IOUtils-Klasse

definiert sehr einfach zu verwendende Hilfsklassen für solche Fälle.

    
Omnaest 27.04.2011 12:45
quelle
0

Laut diesem SO-Beitrag können Sie auch das Scanner klasse eine Einstellung.

    
npinti 27.04.2011 06:45
quelle
0

Ich habe eine sehr einfache Schleife, die etwa 2000 Zeilen (50k Bytes) aus einer Datei auf der SD-Karte liest mit BufferedReader und es liest sie alle in etwa 100mS im Debug-Modus auf Galaxy Registerkarte 2. nicht zu schlecht. Dann legte ich einen Scanner in die Schleife und die Zeit ging durch das Dach (Dutzende von Sekunden), plus viele GC_CONCURANT Nachrichten

%Vor%

so zumindest in meinem Fall ist es der Scanner, der das Problem ist, ich denke, ich muss die INTS auf andere Weise scannen, aber ich habe keine Ahnung, warum es so langsam sein könnte

    
steveh 28.01.2013 11:46
quelle

Tags und Links