Um den schnellsten Weg zu finden, eine Datei Zeile für Zeile zu lesen, müssen Sie ein Benchmarking durchführen. Ich habe einige kleine Tests auf meinem Computer durchgeführt, aber Sie können nicht erwarten, dass meine Ergebnisse für Ihre Umgebung gelten.
Verwenden von StreamReader.ReadLine
Dies ist im Grunde Ihre Methode. Aus irgendeinem Grund setzen Sie die Puffergröße auf den kleinstmöglichen Wert (128). Wenn Sie dies erhöhen, wird die Leistung im Allgemeinen erhöht. Die Standardgröße ist 1.024 und andere gute Optionen sind 512 (die Sektorgröße in Windows) oder 4.096 (die Clustergröße in NTFS). Sie müssen einen Benchmark ausführen, um eine optimale Puffergröße zu ermitteln. Ein größerer Puffer ist - wenn nicht schneller - zumindest nicht langsamer als ein kleinerer Puffer.
const Int32 BufferSize = 128;
using (var fileStream = File.OpenRead(fileName))
using (var streamReader = new StreamReader(fileStream, Encoding.UTF8, true, BufferSize)) {
String line;
while ((line = streamReader.ReadLine()) != null)
// Process line
}
Mit dem FileStream
Konstruktor können Sie FileOptions angeben . Wenn Sie beispielsweise eine große Datei nacheinander von Anfang bis Ende lesen, können Sie davon profitierenFileOptions.SequentialScan
. Auch hier ist Benchmarking das Beste, was Sie tun können.
Verwenden von File.ReadLines
Dies ist Ihrer eigenen Lösung sehr ähnlich, außer dass sie StreamReader
mit einer festen Puffergröße von 1.024 implementiert wird . Auf meinem Computer führt dies zu einer etwas besseren Leistung im Vergleich zu Ihrem Code mit der Puffergröße von 128. Sie können jedoch die gleiche Leistungssteigerung erzielen, indem Sie eine größere Puffergröße verwenden. Diese Methode wird mithilfe eines Iteratorblocks implementiert und belegt nicht für alle Zeilen Speicher.
var lines = File.ReadLines(fileName);
foreach (var line in lines)
// Process line
Verwenden von File.ReadAllLines
Dies ist der vorherigen Methode sehr ähnlich, außer dass diese Methode eine Liste von Zeichenfolgen erstellt, die zum Erstellen des zurückgegebenen Zeilenarrays verwendet werden, sodass die Speicheranforderungen höher sind. Es wird jedoch zurückgegeben und Sie können String[]
nicht IEnumerable<String>
zufällig auf die Zeilen zugreifen.
var lines = File.ReadAllLines(fileName);
for (var i = 0; i < lines.Length; i += 1) {
var line = lines[i];
// Process line
}
Verwenden von String.Split
Diese Methode ist erheblich langsamer, zumindest bei großen Dateien (getestet an einer 511-KB-Datei), wahrscheinlich aufgrund der String.Split
Implementierung. Außerdem wird allen Zeilen ein Array zugewiesen, wodurch der im Vergleich zu Ihrer Lösung erforderliche Speicher erhöht wird.
using (var streamReader = File.OpenText(fileName)) {
var lines = streamReader.ReadToEnd().Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
// Process line
}
Mein Vorschlag ist zu verwenden, File.ReadLines
weil es sauber und effizient ist. Wenn Sie spezielle Freigabeoptionen benötigen (z. B. verwenden FileShare.ReadWrite
), können Sie Ihren eigenen Code verwenden, aber Sie sollten die Puffergröße erhöhen.
Fastest
meinen Sie aus Leistungs- oder Entwicklungsperspektive?