2016-07-12 5 views
1

複雑なSSIS挿入パッケージを実行する前に、(制御ファイルと比較するために)テキストファイルの行数を数えようとしています。C#Streamreader - {CR} {LF}のみで中断

現在、私はStreamReaderを使用していますが、SSISは{CR} {LF}(正しく)を使用していますが、{LF}は新しい行に埋め込まれているため、カウントが集計されません。

{CR} {LF}改行のみに基づいてファイル内の行数を数えることができる代替方法を知っている人はいませんか?予め

おかげ

+3

自分でファイルを読んだり、分割したりできます。単にバイトを読み、{CR} {LF}に遭遇したときに改行を開始するだけです。 – Clint

+0

^- それはStreamReaderがどのようにカバーの下で動作するかです。それはCR、LF、およびCRLFで分割されます –

+0

おそらく、これは..他の行を壊す問題を取り除く高速カスタムストリームリーダーです(記事を参照)。http://stackoverflow.com/questions/17994130/streamreader-with-custom -linebreak-performance-optimization –

答えて

3

CRLFのファイル数とカウント数を繰り返します。

非常に簡単な実装:

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; 
} 

使用例:

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

実際には、文字列のタスクでの検索サブストリングです。より一般的なアルゴリズムを使用することができます。

+0

完璧、ありがとう – user1948635

+1

1文字の最後のバイトがCRに等しく、次の文字の最初のバイトがLFであるUnicodeファイルを越えて実行されないことを願っています。このソリューションは、Unicodeエンコーディングで動作するとは限りません。 –

+0

@JimMischelこれを指摘してくれてありがとう。元の答えは、マルチバイトエンコーディングでは失敗します。修正しました。 – lorond

2

{CR} {LF}が望まれています。本当にどちらが正しいと言うことはできません。

ReadLineメソッドは、行の終わりを取り除きますので、あなたは

使用StreamReader.Read Method()を知っていて、10
続く13のために見ていないそれはのInt

+0

{CR} {LF}はこのファイルに対して正しいですか... – user1948635

2

を返すここではかなり怠惰な方法です...これは読んでますファイル全体をメモリに保存します。

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

サイズのせいでオプション全体が読み込まれませんが、小さなファイルには最適です。 – user1948635