Effiziente Möglichkeit zum löschen einer Zeile aus einer text-Datei
Wie lösche ich eine bestimmte Zeile aus einer text-Datei. Was ist der effizienteste Weg, dies zu tun? Die Datei kann potenziell große(über Millionen Datensätze).
UPDATE:
unten ist der code den ich derzeit benutze, aber ich bin mir nicht sicher, ob es gut ist.
internal void DeleteMarkedEntries() {
string tempPath=Path.GetTempFileName();
using (var reader = new StreamReader(logPath)) {
using (var writer = new StreamWriter(File.OpenWrite(tempPath))) {
int counter = 0;
while (!reader.EndOfStream) {
if (!_deletedLines.Contains(counter)) {
writer.WriteLine(reader.ReadLine());
}
++counter;
}
}
}
if (File.Exists(tempPath)) {
File.Delete(logPath);
File.Move(tempPath, logPath);
}
}
- Wenn du so große Daten speichern, warum bist du nicht mit einer "echten" Datenbank? Ist es eine Einschränkung in dem, was Werkzeuge, die Sie zur Verfügung haben, Ihre aktuellen Fähigkeiten oder den Spezifikationen Ihres Projekts?
- Es ist eine Anforderung, die von 'oben'. Mit echte Datenbank wäre einfacher für mich, aber leider kann ich es nicht verwenden.
- Es ist nicht gut, es ist ein bug - sorry 🙁 - Siehe meine Antwort unten
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den naheliegendsten Weg, dies zu tun ist wahrscheinlich das beste, schreiben der gesamten Datei in eine neue Datei schreiben alle Zeilen außer die mit einem(s) Sie nicht wollen.
Alternativ öffnen Sie die Datei für den wahlfreien Zugriff.
Lesen bis zu dem Punkt, wo Sie wollen, um "löschen" die Zeile.
Überspringen Sie die Zeile zu löschen, und gelesen, dass die Anzahl von bytes (einschließlich der CR + LF - wenn es nötig ist), schreiben Sie, dass die Anzahl der bytes in der Zeile gelöscht, vorher beide Orte durch, die Anzahl der bytes und wiederholen Sie bis zum Ende der Datei.
Hoffe, das hilft.
BEARBEITEN - Jetzt, wo ich den code sehen
Wird nicht funktionieren, wenn Ihr die Linie, die Sie nicht wollen, Sie wollen immer noch, es zu Lesen, nicht nur zu schreiben es. Der obige code weder Lesen oder schreiben. Die neue Datei wird genau das gleiche wie die alte.
Du willst so etwas wie
Text-Dateien werden sequenziell, also, wenn Sie löschen eine Zeile, Sie müssen verschieben alle folgenden Zeilen bis.
Sie können mit " Datei-Zuordnung (eine win32-api, die Sie aufrufen können über PInvoke), um diesen Vorgang ein bisschen weniger schmerzhaft, aber Sie surelly sollte considere eine nicht sequenzielle Struktur, die für Sie Datei, so dass Sie markieren können, eine Zeile als gelöscht, ohne wirklich es zu entfernen aus der Datei... vor Allem, wenn es passieren sollte frenquently.
Wenn ich mich erinnere Datei-Mapping-Api Hinzugefügt werden soll .Net 4.
Wenn Sie absolut haben Verwendung eines text-Datei und kann nicht geändert werden, um eine Datenbank, möchten Sie vielleicht zu benennen, das seltsame symbol am Anfang einer Zeile bedeutet "line deleted". Gerade haben Sie Ihren parser ignoriert diese Zeilen, wie Kommentar-Zeilen in die config-Dateien etc.
Dann regelmäßig ein "compact" - routine, wie Outlook, und die meisten Datenbank-Systeme, die re-schreibt die ganze Datei ohne die gelöschten Zeilen.
Würde ich dringend gehen mit dem Denken, Vor der Codierung, die Antwort die Empfehlung einer Datenbank oder anderen strukturierten Datei.
Je nachdem, was genau zählt als "löschen", Ihre beste Lösung sein mag, überschreiben Sie die betreffende Zeile mit Leerzeichen. Für viele Zwecke (einschließlich menschlichen Verzehr), dies entspricht dem löschen der Zeile völlig. Wenn die resultierende leere Zeile ist ein problem, und Sie sind sicher, Sie nie löschen Sie die erste Zeile, die Sie anfügen können, werden die Leerzeichen der vorherigen Zeile auch überschreiben CRLF mit zwei Räumen.
(Basierend auf dem Kommentar von Bork Blatt Antwort)
Verschieben Sie die Datei in den Speicher mit File-Mapping, wie Denken Sie Vor Der Codierung hat, und Löschungen, die auf den Speicher und nach dem schreiben auf die Festplatte.
Lesen Sie diese Datei Lesen-Benchmarks - C#
C# - Zugriff auf memory-map-Datei
In meinem blog, habe ich ein Benchmark verschiedener I/O-Methoden von C#, um zu bestimmen, die effizientesten Weise zu tun, Datei-I/O. Im Allgemeinen sind Sie besser dran, unter Verwendung der Windows-ReadFile und WriteFile Funktionen. Der nächste Schnellste Weg, um Dateien Lesen in ist durch FileStream. Gute Leistung, Lesen Sie die Dateien in Blöcken zu einer Zeit statt von einer Linie zu einer Zeit, und dann tun Sie Ihre eigene Analyse. Der code, den Sie herunterladen können, von meinem blog gibt Sie ein Beispiel, wie dies zu tun. Es gibt auch eine C# - Klasse, kapselt den Windows-ReadFile /WriteFile Funktionen und ist Recht einfach zu bedienen. Siehe mein blog für weitere details an:
http://designingefficientsoftware.wordpress.com/2011/03/03/efficient-file-io-from-csharp
Bob Bryan MCSD
Lesen die Datei in ein Wörterbuch nicht löschen von Zeilen setzen Sie die int auf 0
auf der Linie müssen Sie markieren als gelöscht gesetzt int in 1. Verwenden Sie ein KeyValuePair zu extrahieren
Zeilen, die nicht benötigt werden gelöscht, und schreiben Sie Sie in eine neue Datei.
Das ist es.