2011-11-08 10 views
3

私は設定ファイルで読んでいるプロジェクトをやっています。設定ファイルは、 "D 1 1"、 "C 2 2"などの文字列の一覧にすぎません。今ではC#で読み書きをしていないので、オンラインで見て、何らかの演奏を見つけようとしていますC/C++ .eof()の私は1つを見つけることができませんでした。StreamReader.EndOfStreamを使用する際の問題?

は、だから私が持っているものは、オンライン、私は、ファイルの最後まで読みすることが分かっ方法の...全ての例

TextReader tr = new StreamReader("/mypath"); 

で発生したままの2つの例では、

while ((line = tr.ReadLine() != null) 

ありましたまたは

while (tr.Peek() >= 0) 

私はStreamReaderをはブールEndOfStreamを持っていますが、誰が信じるように私を導いていることを示唆しなかったことに気づきましたその解決策に何か問題がありました。私は

while (!(tr as StreamReader).EndOfStream) 

...このようにそれをしようとしてしまった、それだけで正常に動作するようです。

私は私の質問は、StreamReaderとしてTextReaderをキャストし、EndOfStreamをチェックする際に問題が発生すると思いますか?

+1

それは素晴らしいです。しかし、キャストはブラックボード上に釘です。 * as *を使うのはここでは間違いです。それは良いInvalidCastの代わりにちょっとしたNullReference例外を生成するだけです。 –

答えて

5

明らかな欠点の1つは、コードがStreamReaderに限定されていることです。あなたはのコードを簡単に書いてTextReaderと書くことができます。そうすれば、単体テストなどのためにStringReader(または類似のもの)を使用する必要がある場合は、何の問題もありません。

個人的に私はいつも、「それがnullになるまでのラインを読んで」アプローチを使用する - 時には、拡張メソッドを経由して私は、反復子ブロックを使用してTextReader上の拡張メソッドになり

foreach (string line in reader.EnumerateLines()) 
{ 
} 

EnumerateLinesを使用できるようにします。 (これは簡単にLINQなどにも使用できることを意味します)。

+0

ユニットテスティングでナイスキャッチ。 +1 – eandersson

+0

それは良い点です。私は拡張メソッドの考え方が気に入っていますが、テストケースの実行を開始するときにはおそらく設定ファイルから切り替えることになります。 – MattMacdonald

+0

@MattMacdonald:これは設定を使用するテストコードの点では良いことですが、これは設定ファイルをロードするコードのテストはどうですか? :) –

3

またはあなたのコードを簡素化するために、ReadAllLinesを使用することができます。

http://msdn.microsoft.com/en-us/library/s2tte0y1.aspx

この道を、あなたは.NETがすべてのEOF/EOL管理の世話を聞かせて、あなたはあなたのコンテンツに焦点を当てます。

+3

それは、あなたが*ファイル*を読むことに結びついています。実際のロジックを扱うコードに 'TextReader'を渡すことができればいいです。つまり、' StringReader'を使ってユニットテストをすることができます。 –

+0

@JonSkeet洞察に感謝します:) – jv42

+0

TextReaderには、同じことをやっているReadToEnd()があります。私はそれをやろうと考えていたが、まだそれほどコードを単純化していない。 – MattMacdonald

0

まあ、StreamReaderは、TextReaderの特殊化です。つまり、StreamReaderはTextReaderを継承します。だから問題はないはずです。 :)

1

問題は発生しません。

public bool EndOfStream 
{ 
    get 
    { 
     if (this.stream == null) 
     { 
      __Error.ReaderClosed(); 
     } 
     if (this.charPos < this.charLen) 
     { 
      return false; 
     } 
     int num = this.ReadBuffer(); 
     return num == 0; 
    } 
} 

は勿論でキャスト:あなたはEndToStreamかの実装を見れば、あなたはそれが基本となるストリームからより多くのデータを読み取ることができれば、それだけで、まだバッファにデータが存在するかどうかを確認していない場合ことがわかりますそのようなあなたのコードは、それがかなり始まっていないあなたの読者の実際のタイプであるStreamReaderに依存するようになります。

0

たぶん文字列にそれをすべて読んで、それを解析:StreamReader.ReadToEnd()

using (StreamReader sr = new StreamReader(path)) 
{ 
    //This allows you to do one Read operation. 
    string contents = sr.ReadToEnd()); 
} 
関連する問題