[Bearbeiten]
Wenn Sie dies tun, um den Anfang einer Protokolldatei zu kürzen, können Sie das Laden der gesamten Datei vermeiden, indem Sie wie folgt vorgehen:
// count the number of lines in the file
int count = 0;
using (var sr = new StreamReader("file.txt"))
{
while (sr.ReadLine() != null)
count++;
}
// skip first (LOG_MAX - count) lines
count = LOG_MAX - count;
using (var sr = new StreamReader("file.txt"))
using (var sw = new StreamWriter("output.txt"))
{
// skip several lines
while (count > 0 && sr.ReadLine() != null)
count--;
// continue copying
string line = "";
while ((line = sr.ReadLine()) != null)
sw.WriteLine(line);
}
Zunächst einmal, da File.ReadAllLines
lädt die gesamte Datei in ein String-Array ( string[]
), ist das Kopieren in eine Liste überflüssig.
Zweitens: Sie müssen verstehen, dass ein List
ist unter der Haube mit einem dynamischen Array implementiert. Dies bedeutet, dass die CLR mehrere Arrays zuweisen und kopieren muss, bis sie die gesamte Datei aufnehmen kann. Da sich die Datei bereits auf der Festplatte befindet, sollten Sie in Erwägung ziehen, Geschwindigkeit gegen Speicher zu tauschen und die Daten direkt auf der Festplatte zu bearbeiten oder sie in kleineren Teilen zu verarbeiten.
-
Wenn Sie es vollständig in den Speicher laden müssen, versuchen Sie zumindest, es in einem Array zu belassen:
string[] lines = File.ReadAllLines("file.txt");
-
Wenn es wirklich eine sein muss List
laden Sie die Zeilen nacheinander:
List<string> lines = new List<string>();
using (var sr = new StreamReader("file.txt"))
{
while (sr.Peek() >= 0)
lines.Add(sr.ReadLine());
}
Nota: List<T>
hat einen Konstruktor, der einen Kapazitätsparameter annimmt. Wenn Sie die Anzahl der Zeilen im Voraus kennen, können Sie Mehrfachzuweisungen verhindern, indem Sie das Array im Voraus zuweisen:
List<string> lines = new List<string>(NUMBER_OF_LINES);
-
Noch besser ist es, wenn Sie nicht die gesamte Datei im Speicher ablegen, sondern sie "on the fly" verarbeiten:
using (var sr = new StreamReader("file.txt"))
{
string line;
while ((line = sr.ReadLine()) != null)
{
// process the file line by line
}
}