Ich möchte nur die letzte Zeile einer Textdatei lesen (ich bin auf UNIX, kann Boost verwenden). Alle Methoden, die ich kenne, erfordern das Durchsuchen der gesamten Datei, um die letzte Zeile zu erhalten, die überhaupt nicht effizient ist. Gibt es einen effizienten Weg, nur die letzte Zeile zu bekommen?
Außerdem muss das so robust sein, dass es auch funktioniert, wenn die betreffende Textdatei ständig von einem anderen Prozess angehängt wird.
Verwenden Sie seekg, um zum Ende der Datei zu springen, und lesen Sie dann zurück, bis Sie den ersten Zeilenumbruch gefunden haben. Unten ist ein Beispielcode von der Spitze meines Kopfes mit MSVC.
%Vor%Und unten ist eine Testdatei. Es ist erfolgreich mit leeren, einzeiligen und mehrzeiligen Daten in der Textdatei.
%Vor%Springe zum Ende und lese Blöcke rückwärts, bis du die Kriterien für eine Linie gefunden hast. Wenn der letzte Block nicht mit einer Linie "endet", müssen Sie wahrscheinlich auch versuchen, vorwärts zu scannen (vorausgesetzt, dass eine wirklich lange Linie in einer aktiv an die Datei angehängt ist).
Sie können seekg () benutzen, um zum Ende der Datei zu springen, und rückwärts lesen, der Pseudo-Code ist wie folgt:
%Vor%Obwohl die Antwort von derpface definitiv korrekt ist, liefert sie oft unerwartete Ergebnisse. Der Grund dafür ist, dass zumindest auf meinem Betriebssystem (Mac OS X 10.9.5) viele Texteditoren ihre Dateien mit einem "End Line" -Zeichen beenden.
Zum Beispiel, wenn ich vim öffne, tippe nur das einzelne Zeichen 'a' (keine Rückkehr), und speichere, die Datei enthält nun (in hexadezimal):
%Vor%Wobei 61 der Buchstabe 'a' und 0A ein Zeilenendezeichen ist.
Dies bedeutet, dass der Code von derpface eine leere Zeichenfolge für alle Dateien zurückgibt, die von einem solchen Texteditor erstellt wurden.
Obwohl ich mir durchaus vorstellen kann, dass Fälle, in denen eine mit einer Endzeile abgeschlossene Datei die leere Zeichenfolge zurückgeben sollte, wäre es für normale Textdateien besser, das letzte Zeichen der Endzeile zu ignorieren. Wenn die Datei durch ein 'end line' Zeichen beendet wird, ignorieren wir sie ordnungsgemäß und wenn die Datei nicht durch ein 'end line' Zeichen beendet wird, müssen wir sie nicht überprüfen.
Mein Code zum Ignorieren des letzten Zeichens der Eingabedatei ist:
%Vor%Was wird ausgegeben:
%Vor%In der einzelnen 'a' Datei.
EDIT: Die Zeile if((int)fin.tellg() <= 0){
verursacht tatsächlich Probleme, wenn die Datei zu groß ist (& gt; 2GB), weil tellg nicht nur die Anzahl der Zeichen vom Anfang der Datei zurückgibt ( tellg () -Funktion geben falsche Dateigröße? ). Es kann besser sein, für den Anfang der Datei fin.tellg()==tellgValueForStartOfFile
und für Fehler fin.tellg()==-1
separat zu testen. Die tellgValueForStartOfFile
ist wahrscheinlich 0, aber ein besserer Weg wäre sicher:
Ich habe auch mit dem Problem gekämpft, weil ich den Code von uberwulu durchgelaufen bin und auch eine Leerzeile bekommen habe. Hier ist was ich gefunden habe. Ich verwende die folgende .csv-Datei als Beispiel:
%Vor%Um die Befehle im Code zu verstehen, beachten Sie bitte die folgenden Positionen und die entsprechenden Zeichen. (Loc, char): ... (63, '3'), (64, '5'), (65, -), (66, '\ n'), (EOF, -).
%Vor% Ursprünglich sollte dies der letzte Syslog-Eintrag sein. Da das letzte Zeichen vor dem EOF '\n'
ist, suchen wir zurück, um das nächste Vorkommen von '\n'
zu finden, und speichern dann die Zeile in einer Zeichenkette.