2009-07-17 21 views
2

ログファイルを行ごとに読み込む必要があります。サイズは約6MB、合計は40000行です。しかし、私のプログラムをテストした後、私はそのログファイルがLFキャラクタだけで区切られていることを発見しました。だから使用できませんReadlineStreamReaderクラスのメソッドLFで区切られたファイル内の各行を読み取る方法は?

どうすればこの問題を解決できますか?

編集:私はテキストリーダーを使用しようとしましたが、私のプログラムはまだ動作しませんでした:LF行が終わると

using (TextReader sr = new StreamReader(strPath, Encoding.Unicode)) 
      { 


       sr.ReadLine(); //ignore three first lines of log file 
       sr.ReadLine(); 
       sr.ReadLine(); 

       int count = 0; //number of read line 
       string strLine; 
       while (sr.Peek()!=0) 
       { 
        strLine = sr.ReadLine(); 
        if (strLine.Trim() != "") 
        { 
         InsertData(strLine); 
         count++; 
        } 
       } 

       return count; 
      } 

答えて

4

File.ReadAllLines(filename)は、正しくファイルをロードしませんか?ファイル全体が必要な場合はこれを使用します。別の方法よりも速度が遅いことを示すサイトを見ましたが、正しいエンコーディング(デフォルトはUTF-8)を渡しても、それほどきれいです。

編集:そうです。また、ストリーミングが必要な場合、TextReader.ReadLine()はUnixの行末も正しく処理します。

もう一度編集:StreamReaderも同様です。あなたはドキュメントをチェックして、LFの行末を処理しないと仮定しましたか?私はリフレクターを見ていて、それは適切な処理ルーチンのように思える。

+0

実際にファイルが大きくなります。私は後処理のために行ごとに – Vimvq1987

+0

@ Vimvq1987(4年後...)を読む必要がありますが、これでどのように問題が解決されましたか? IOW、これが正しい場合、あなたのコードは別の理由で失敗していました。好奇心から(そして覚えていれば)それは何ですか? –

8

TextReader.ReadLineはすでに\nで終了した行を処理しています。

the docs

から:

ラインがキャリッジリターン (0x000d)、ラインフィード(0x000a)、 ラインフィードに続くキャリッジリターン続い 文字の配列として定義されます、Environment.NewLine、またはストリームマーカーの末尾 。 が返された文字列には、末尾の改行コード および/または 改行が含まれていません。入力ストリーム の最後に達した場合、返される値は null参照(Visual のNothing)です。

だから、基本的には大丈夫です。 (つまり、メソッドが宣言されているところですので、私は約TextReaderではなくStreamReader話をしました - 。明らかにそれはまだStreamReaderで動作します)

あなたは(ログファイルに対してLINQを使用して、潜在的にして)簡単にラインを反復処理したい場合MiscUtilの私のLineReaderクラスが役に立ちます。それは基本的にイテレータでReadLine()への呼び出しをラップします。だから、例えば、あなたが行うことができます:

var query = from file in Directory.GetFiles("logs") 
      from line in new LineReader(file) 
      where !line.StartsWith("DEBUG") 
      select line; 

foreach (string line in query) 
{ 
    // ... 
} 

すべてのストリーミング:)

+0

私のプログラムはまだ動作しませんでした。私は何が間違っているのか分かりません:( – Vimvq1987

0

私は推測していると思います\ LF(\ n)が\ CR(\ r)はのみの問題を引き起こす可能性があるのに対し、(罰金だろう)。

ターミネータを読むと、一度に1行ずつ文字を読み取り、処理できます。

プロファイリング後、これが遅すぎると、app-side-bufferingをread([])で使用できます。しかし、簡単な文字を一度に試してみてください!

+0

この機能を実装する高速機能があります。高速で、短く、表現力豊かで標準化されているため、これらの機能を最初に試してください。 –

0

または、読み取りブロックメソッドを使用して、自分で行を解析することができます。