2016-07-12 29 views
1

Ich versuche die Anzahl der Zeilen in einer Textdatei zu zählen (mit einer Steuerdatei zu vergleichen), bevor ein komplexes SSIS-Einfügepaket ausgeführt wird.C# Streamreader - Unterbrechung nur bei {CR} {LF}

Momentan verwende ich einen StreamReader und es bricht eine Zeile mit einem eingebetteten {LF} in eine neue Zeile, während SSIS {CR} {LF} (korrekt) verwendet, so dass die Zählungen nicht übereinstimmen.

Kennt jemand eine alternative Methode, dies zu tun, wo ich die Anzahl der Zeilen in der Datei basierend auf {CR} {LF} nur Zeilenumbrüche zählen kann?

Vielen Dank im Voraus

+3

Sie könnten einfach die Datei selbst lesen und teilen, wie Sie wollen; Lies einfach die Bytes und wenn du auf {CR} {LF} stößt, dann starte einfach eine neue Zeile. – Clint

+0

^- so arbeitet StreamReader unter der Decke. Nun, es teilt sich auf CR, LF und CRLF –

+0

Vielleicht hilft das .. schnelle benutzerdefinierte Stream-Reader, die auch andere Zeilenumbrüche Probleme loswerden (siehe Beitrag) http://StackOverflow.com/questions/17994130/streamreader-with-custom -linebreak-performance-optimization –

Antwort

3

Iterieren durch die Datei und Zählen der Anzahl der CRLFs.

recht einfache Implementierung:

public int CountLines(Stream stream, Encoding encoding) 
{ 
    int cur, prev = -1, lines = 0; 
    using (var sr = new StreamReader(stream, encoding, false, 4096, true)) 
    { 
     while ((cur = sr.Read()) != -1) 
     { 
      if (prev == '\r' && cur == '\n') 
       lines++; 

      prev = cur; 
     } 
    } 

    //Empty stream will result in 0 lines, any content would result in at least one line 
    if (prev != -1) 
     lines++; 

    return lines; 
} 

Beispiel Nutzung:

using(var s = File.OpenRead(@"<your_file_path>")) 
    Console.WriteLine("Found {0} lines", CountLines(s, Encoding.Default)); 

Eigentlich ist es ein Fund String in String-Aufgabe. Mehr generische Algorithmen können verwendet werden.

+0

Perfekt, danke – user1948635

+1

Ich hoffe, Sie laufen nicht über eine Unicode-Datei, in der das letzte Byte eines Zeichens gleich CR ist, und das erste Byte des nächsten Zeichens ist LF. Sie sollten in Ihrer Antwort unbedingt beachten, dass diese Lösung nicht für jede Unicode-Codierung geeignet ist. –

+0

@JimMischel Vielen Dank, dass Sie darauf hingewiesen haben. Die ursprüngliche Antwort würde bei jeder Multi-Byte-Codierung fehlschlagen. Behoben. – lorond

2

{CR} {LF} ist das gewünschte. Kann nicht wirklich sagen, was richtig ist.

Da Readline das Ende der Linie abstreift Sie nicht wissen,

Verwenden StreamReader.Read Method() und suchen Sie nach 13 gefolgt von 10
Es zurückkehren Int

+0

{CR} {LF} ist richtig für diese Datei ist, was das bedeutet ... – user1948635

2

Hier ist eine ziemlich faule Weise ... das wird gelesen die gesamte Datei in den Speicher.

var cnt = File.ReadAllText("yourfile.txt") 
       .Split(new[] { "\r\n" }, StringSplitOptions.None) 
       .Length; 
+0

Das Lesen der ganzen Datei in einem Rutsch ist keine Option aufgrund der Größe, aber nette Lösung für kleinere Dateien. – user1948635