Frage

Gibt es eine einfache Möglichkeit, programmatisch die Anzahl der Zeilen in einer Textdatei zu bestimmen?

War es hilfreich?

Lösung

Im Ernst verspätetes edit: Wenn Sie .NET 4.0 oder höher

mit

Die File Klasse hat eine neue ReadLines Methode, die Linien lazily aufzählt anstatt sie alle in einem Array wie ReadAllLines gierig zu lesen. So, jetzt können Sie sowohl Effizienz und Prägnanz mit haben:

var lineCount = File.ReadLines(@"C:\file.txt").Count();

Original Antwort

Wenn Sie sich auch nicht um Effizienz gestört, können Sie einfach schreiben:

var lineCount = File.ReadAllLines(@"C:\file.txt").Length;

Für eine effizientere Methode könnten Sie tun:

var lineCount = 0;
using (var reader = File.OpenText(@"C:\file.txt"))
{
    while (reader.ReadLine() != null)
    {
        lineCount++;
    }
}

Edit: Als Antwort auf Fragen zu Effizienz

Der Grund sagte ich das zweite effizienter war, in Bezug auf die Speichernutzung, die nicht unbedingt beschleunigen. Die erste lädt den gesamten Inhalt der Datei in eine Anordnung, die bedeutet, dass es zumindest so viel Speicher wie die Größe der Datei zuordnen muss. Die zweite Schleife nur eine Zeile zu einer Zeit, so dass es nie zu einem Zeitpunkt mehr als eine Zeile im Wert von Speicher zugewiesen hat. Das ist nicht so wichtig für kleine Dateien, aber für größere Dateien könnte es ein Problem sein (wenn Sie versuchen, die Anzahl der Zeilen in einer 4 GB-Datei auf einem 32-Bit-System, zum Beispiel, wo es einfach nicht genug ist Benutzermodus-Adressraum ein Array diese große) zuzuteilen.

In Bezug auf die Geschwindigkeit erwarte ich würde nicht viel drin sein. Es ist möglich, dass ReadAllLines einige interne Optimierungen, aber auf der anderen Seite kann es haben einen massiven Teil des Speichers zuzuweisen. Ich würde vermuten, dass ReadAllLines könnte für kleine Dateien schneller, aber deutlich langsamer für große Dateien; obwohl der einzige Weg, um es mit einer Stoppuhr oder Code Profiler zu messen wäre zu sagen.

Andere Tipps

Die einfachste:

int lines = File.ReadAllLines("myfile").Length;

Dies würde verwenden weniger Speicher, aber wahrscheinlich länger dauern

int count = 0;
string line;
TextReader reader = new StreamReader("file.txt");
while ((line = reader.ReadLine()) != null)
{
  count++;
}
reader.Close();

Wenn durch einfach meinen Sie einen Codezeile, die leicht zu entziffern, aber pro Chance ineffizient?

string[] lines = System.IO.File.RealAllLines($filename);
int cnt = lines.Count();

Das ist wahrscheinlich der schnellste Weg, wie viele Zeilen zu kennen.

Sie könnten auch tun (je nachdem, ob Sie es in puffern)

#for large files
while (...reads into buffer){
string[] lines = Regex.Split(buffer,System.Enviorment.NewLine);
}

Es gibt noch zahlreiche andere Möglichkeiten, aber eine der oben ist wahrscheinlich das, was Sie mit gehen werden.

Sie es schnell in lesen können, und einen Zähler erhöhen, nur eine Schleife verwenden zu erhöhen, nichts mit dem Text zu tun.

die Zeilenumbrüche zählen / Line-Feeds. Ich glaube, in Unicode sie sind immer noch 0x000D und 0x000A sind. auf diese Weise können Sie so effizient oder als ineffizient sein, wie Sie wollen, und entscheiden, ob Sie mit den beiden Zeichen zu tun haben oder nicht

Ein gangbarer Weg, und eine, die ich persönlich in Anspruch genommen haben, wäre eine eigene Kopfzeile der ersten Zeile der Datei hinzuzufügen. Ich tat dies für ein individuelles Modell Format für mein Spiel. Grundsätzlich habe ich ein Tool, das meine OBJ-Dateien optimiert, das Loswerden der Mist brauche ich nicht, wandelt sie in ein besseres Layout und schreibt dann die Gesamtzahl der Zeilen, Gesichter, Normalen, Ecken und Textur UVs auf die erste Zeile. Diese Daten werden dann durch verschiedene Array-Puffer verwendet wird, wenn das Modell geladen wird.

Dies ist auch nützlich, weil man nur einmal eine Schleife durch die Datei benötigt sie in zu laden, statt einmal die Linien zu zählen und die Daten wieder in Ihre erstellten Puffer zu lesen.

Lesen einer Datei an und für sich dauert einige Zeit, Müll das Ergebnis sammeln weiteres Problem ist, wie Sie die gesamte Datei lesen Sie einfach die Newline-Zeichen zu zählen (s),

An einem gewissen Punkt, jemand zu haben, die Zeichen in der Datei zu lesen, unabhängig davon, ob dies der Rahmen oder wenn es Ihr Code. Das heißt, Sie haben die Datei zu öffnen und es in den Speicher geladen, wenn die Datei groß ist dies möglicherweise wird ein Problem sein, da der Speicher Müll gesammelt werden muss.

Nima Ara eine nette Analyse dass Sie

berücksichtigen könnten

Hier wird die Lösung vorgeschlagen, wie es in einer Zeit, 4 Zeichen liest, zählt die Zeilenvorschub und erneut verwendet die gleiche Speicheradresse wieder für das nächste Zeichen Vergleich.

private const char CR = '\r';  
private const char LF = '\n';  
private const char NULL = (char)0;

public static long CountLinesMaybe(Stream stream)  
{
    Ensure.NotNull(stream, nameof(stream));

    var lineCount = 0L;

    var byteBuffer = new byte[1024 * 1024];
    const int BytesAtTheTime = 4;
    var detectedEOL = NULL;
    var currentChar = NULL;

    int bytesRead;
    while ((bytesRead = stream.Read(byteBuffer, 0, byteBuffer.Length)) > 0)
    {
        var i = 0;
        for (; i <= bytesRead - BytesAtTheTime; i += BytesAtTheTime)
        {
            currentChar = (char)byteBuffer[i];

            if (detectedEOL != NULL)
            {
                if (currentChar == detectedEOL) { lineCount++; }

                currentChar = (char)byteBuffer[i + 1];
                if (currentChar == detectedEOL) { lineCount++; }

                currentChar = (char)byteBuffer[i + 2];
                if (currentChar == detectedEOL) { lineCount++; }

                currentChar = (char)byteBuffer[i + 3];
                if (currentChar == detectedEOL) { lineCount++; }
            }
            else
            {
                if (currentChar == LF || currentChar == CR)
                {
                    detectedEOL = currentChar;
                    lineCount++;
                }
                i -= BytesAtTheTime - 1;
            }
        }

        for (; i < bytesRead; i++)
        {
            currentChar = (char)byteBuffer[i];

            if (detectedEOL != NULL)
            {
                if (currentChar == detectedEOL) { lineCount++; }
            }
            else
            {
                if (currentChar == LF || currentChar == CR)
                {
                    detectedEOL = currentChar;
                    lineCount++;
                }
            }
        }
    }

    if (currentChar != LF && currentChar != CR && currentChar != NULL)
    {
        lineCount++;
    }
    return lineCount;
}

Vor Ihnen sehen können, dass eine Linie ein Zeichen in einer Zeit von dem zugrunde liegenden Rahmen auch gelesen wird, wie Sie alle Zeichen lesen, müssen Sie den Zeilenvorschub zu sehen.

Wenn Sie es als getan Bucht Nima Profil würden Sie sehen, dass dies eine ziemlich schnelle und effiziente Art und Weise, dies zu tun.

try {
    string path = args[0];
    FileStream fh = new FileStream(path, FileMode.Open, FileAccess.Read);
    int i;
    string s = "";
    while ((i = fh.ReadByte()) != -1)
        s = s + (char)i;

    //its for reading number of paragraphs
    int count = 0;
    for (int j = 0; j < s.Length - 1; j++) {
            if (s.Substring(j, 1) == "\n")
                count++;
    }

    Console.WriteLine("The total searches were :" + count);

    fh.Close();

} catch(Exception ex) {
    Console.WriteLine(ex.Message);
}         

Sie können starten Sie die " wc .exe" ausführbare Datei ( kommt mit UnixUtils und Installation nicht braucht) als externen Prozess ausgeführt. Es unterstützt verschiedene Zeilenzahl Methoden (wie Unix vs Mac vs Windows).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top