Um den schnellsten Weg zu finden, eine Datei Zeile für Zeile zu lesen, müssen Sie einige Vergleiche anstellen. Ich habe einige kleine Tests auf meinem Computer durchgeführt, aber Sie können nicht erwarten, dass meine Ergebnisse auf Ihre Umgebung zutreffen.
Verwendung von StreamReader.ReadLine
Das ist im Grunde Ihre Methode. Aus irgendeinem Grund setzen Sie die Puffergröße auf den kleinstmöglichen Wert (128). Wenn Sie diesen Wert erhöhen, wird die Leistung im Allgemeinen gesteigert. Die Standardgröße ist 1.024 und andere gute Wahlmöglichkeiten sind 512 (die Sektorgröße in Windows) oder 4.096 (die Clustergröße in NTFS). Um die optimale Puffergröße zu ermitteln, müssen Sie einen Benchmark-Test durchführen. Ein größerer Puffer ist - wenn nicht schneller - so doch 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
}
}
Le site FileStream
Konstruktor können Sie angeben FileOptions . Wenn Sie beispielsweise eine große Datei sequentiell von Anfang bis Ende lesen, können Sie von folgenden Vorteilen profitieren FileOptions.SequentialScan
. Auch hier ist ein Benchmarking das Beste, was Sie tun können.
File.ReadLines verwenden
Diese Lösung ist Ihrer eigenen sehr ähnlich, außer dass sie mit einer StreamReader
mit einer festen Puffergröße von 1.024. Auf meinem Computer führt dies zu einer etwas besseren Leistung als Ihr Code mit der Puffergröße von 128. Sie können jedoch die gleiche Leistungssteigerung erzielen, wenn Sie eine größere Puffergröße verwenden. Diese Methode ist mit einem Iteratorblock implementiert und verbraucht nicht für alle Zeilen Speicher.
var lines = File.ReadLines(fileName);
foreach (var line in lines)
// Process line
File.ReadAllLines verwenden
Diese Methode ähnelt der vorhergehenden, mit dem Unterschied, dass sie eine Liste von Zeichenketten anlegt, die zur Erstellung des zurückgegebenen Zeilenarrays verwendet wird, so dass der Speicherbedarf höher ist. Sie gibt jedoch zurück String[]
und nicht ein IEnumerable<String>
die es Ihnen ermöglichen, die Zeilen nach dem Zufallsprinzip aufzurufen.
var lines = File.ReadAllLines(fileName);
for (var i = 0; i < lines.Length; i += 1) {
var line = lines[i];
// Process line
}
String.Split verwenden
Diese Methode ist erheblich langsamer, zumindest bei großen Dateien (getestet mit einer 511 KB großen Datei), was wahrscheinlich darauf zurückzuführen ist, wie String.Split
umgesetzt wird. Außerdem wird ein Array für alle Zeilen zugewiesen, was den Speicherbedarf im Vergleich zu Ihrer Lösung erhöht.
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 die Verwendung von File.ReadLines
weil es sauber und effizient ist. Wenn Sie spezielle Freigabeoptionen benötigen (z. B. wenn Sie FileShare.ReadWrite
), können Sie Ihren eigenen Code verwenden, aber Sie sollten die Puffergröße erhöhen.