Gibt es Tricks, um die Anzahl der Zeilen in einer Textdatei zu zählen? [geschlossen]

8

Angenommen, Sie haben eine Textdatei - was ist die schnellste und / oder speicherfreundlichste Methode, um die Anzahl der Textzeilen in dieser Datei zu bestimmen?

Geht es einfach darum, Zeichen für Zeichen durchzusehen und nach neuen Zeilen zu suchen?

    
xyz 09.10.2009, 18:25
quelle

7 Antworten

11

Wahrscheinlich nicht der schnellste, aber der vielseitigste ...

%Vor%

... das wird wahrscheinlich schneller sein ...

Wenn Sie noch mehr Geschwindigkeit benötigen, können Sie ein Duff-Gerät ausprobieren und überprüfe 10 oder 20 Bytes vor der Verzweigung

%Vor%     
Matthew Whited 09.10.2009, 18:29
quelle
10

Wenn Sie keine feste Zeilenlänge (in Form von Bytes ) haben, müssen Sie die Daten unbedingt lesen. Ob Sie die Konvertierung aller Daten in Text vermeiden können, hängt von der Codierung ab.

Jetzt ist der effizienteste Weg Reiniers - Zeilenenden manuell zu zählen. Der einfachste Code würde jedoch TextReader.ReadLine() verwenden. Und in der Tat wäre der einfachste Weg das zu tun, meine LineReader -Klasse von MiscUtil zu verwenden, die a Dateiname (oder verschiedene andere Dinge) in ein IEnumerable<string> . Sie können dann einfach LINQ verwenden:

%Vor%

(Wenn Sie nicht die gesamte MiscUtil-Datei verwenden möchten, können Sie nur LineReader von diese Antwort .)

Nun wird das eine Menge Müll erzeugen, der nicht immer in dasselbe Char-Array eingelesen werden würde - aber es wird nicht mehr als eine Zeile nach der anderen lesen, also werden Sie den GC ein bisschen stressen, aber es ist nicht mit großen Dateien in die Luft gehen. Es erfordert auch die Decodierung aller Daten in Text - die Sie können können wegkommen, ohne für einige Kodierungen zu tun.

Persönlich ist das der Code, den ich verwenden würde, bis ich feststelle, dass es einen Engpass verursacht hat - es ist viel einfacher, richtig zu machen, als es manuell zu tun. Wissen Sie absolut , dass in Ihrer jetzigen Situation Code wie oben der Flaschenhals sein wird?

Wie immer sollten Sie nicht so lange optimieren, bis Sie müssen ... und Sie können dies sehr einfach zu einem späteren Zeitpunkt optimieren, ohne Ihr Gesamtdesign zu ändern, so dass ein Verschieben nicht schädlich ist. p>

BEARBEITEN: Um die Antwort von Matthew zu einer zu konvertieren, die für jede Kodierung funktioniert - die aber die Strafe für die Dekodierung aller Daten mit sich bringt, können Sie natürlich mit etwas wie dem folgenden Code enden. Ich gehe davon aus, dass Sie nur um \n - anstatt um \r , \n und \r\n , die TextReader normalerweise behandelt:

kümmern %Vor%     
Jon Skeet 09.10.2009 18:34
quelle
5

Wenn es sich um einen festen Datensatz handelt, können Sie die Größe eines Datensatzes ermitteln und dann die gesamte Dateigröße durch diesen Betrag teilen, um die Anzahl der Datensätze zu erhalten. Wenn Sie nur nach einer Schätzung suchen, was ich in der Vergangenheit getan habe, lesen Sie einfach die ersten x Zeilen (z. B. 200) und verwenden Sie diese, um eine durchschnittliche Zeilengröße zu erhalten, die Sie dann verwenden können, um die Gesamtzahl zu erraten von Datensätzen (teilen Sie die Gesamtdateigröße nach der durchschnittlichen Zeilengröße). Dies funktioniert gut, wenn Ihre Aufzeichnungen ziemlich einheitlich sind und Sie keine genaue Anzahl benötigen. Ich habe dies für große Dateien verwendet (machen Sie eine schnelle Überprüfung, um die Dateigröße zu ermitteln, wenn es über 20 MB ist, dann erhalten Sie eine Schätzung, anstatt die gesamte Datei zu lesen).

Abgesehen davon ist die einzige 100% genaue Möglichkeit, die Datei zeilenweise mit ReadLine durchzugehen.

    
TLiebe 09.10.2009 18:29
quelle
3

Ich würde es lesen 32kb zu einem Zeitpunkt (oder mehr), zählen Sie die Anzahl der \ r \ n's im Speicherblock und wiederholen, bis fertig.

    
Toad 09.10.2009 18:27
quelle
2

Das einfachste:

%Vor%

Dies wird natürlich die gesamte Datei in den Speicher lesen, so dass es überhaupt nicht speichereffizient ist. Am effizientesten ist es, die Datei als Stream zu lesen und nach den Zeilenumbruchzeichen zu suchen. Dies wird auch der schnellste sein, da es ein Minimum an Overhead ist.

Es gibt keine Verknüpfung, die Sie verwenden können. Dateien sind nicht linienbasiert, daher gibt es keine zusätzlichen Informationen, die Sie verwenden können, auf die eine Weise müssen Sie jedes einzelne Byte der Datei lesen und untersuchen.

    
Guffa 09.10.2009 18:38
quelle
1

Ich glaube, Windows verwendet zwei Zeichen, um das Ende der Zeile zu markieren (10H und 13H, wenn ich mich richtig erinnere), so dass Sie nur jedes zweite Zeichen auf diese beiden überprüfen müssen.

    
Emilio M Bumachar 09.10.2009 18:57
quelle
1

Da es sich um einen rein sequenziellen Prozess ohne Abhängigkeiten zwischen den Standorten handelt, sollten Sie die Verwendung von map / reduce berücksichtigen, wenn die Daten wirklich riesig sind. In C / C ++ können Sie OpenMP für Parallelität verwenden. Jeder Thread liest einen Chunk und zählt CRLF in diesem Chunk. Schließlich werden sie im reduzierten Teil ihre individuellen Zählungen summieren. Intel Threading-Bausteine ​​bieten Ihnen C ++ - basierte Vorlagenkonstrukte für die Parallelität. Ich stimme zu, dass dies ein Vorschlaghammerhammer für kleine Dateien ist, aber aus reiner Leistungsperspektive ist dies optimal (Teile und herrsche)

    
hackworks 14.10.2009 10:43
quelle

Tags und Links