web-dev-qa-db-ja.com

バイナリリーダーのファイルの終わりをチェックするC#

バイナリリーダーのファイルの最後に到達したかどうかを確認する方法を探していましたが、PeekCharをそのように使用することを提案しました

while (inFile.PeekChar() > 0)
{
    ...
}

ただし、問題が発生したようです

未処理の例外:System.ArgumentException:出力charバッファーはsma 
 llでデコードされた文字を格納できないため、 'Unicode(UTF-8)'フォールバック 'Syste 
 mをエンコードしています。 Text.DecoderReplacementFallback '。
パラメーター名:chars 
 at System.Text.Encoding.ThrowCharsOverflow()
 at System.Text.Encoding.ThrowCharsOverflow(DecoderNLS decoder、Boolean nothin 
 gDecoded)
 at System.Text.UTF8Encoding.GetChars(Byte * bytes、Int32 byteCount、Char * char 
 s、Int32 charCount、DecoderNLS baseDecoder)
 at System。 Text.DecoderNLS.GetChars(Byte * bytes、Int32 byteCount、Char * chars、
 Int32 charCount、Boolean flush)
 at System.Text.DecoderNLS.GetChars(Byte [] bytes、Int32 byteIndex、 Int32 byteC 
 ount、Char [] chars、Int32 charIndex、Boolean flush)
 at System.Text.DecoderNLS.GetChars(Byte [] bytes、Int32 byteIndex、Int32 byteC 
 ount 、Char [] chars、Int32 charIndex)
 at System.IO.BinaryReader.InternalR eadOneChar()
 at System.IO.BinaryReader.PeekChar()

したがって、PeekCharはそれを行うのに最適な方法ではないかもしれません。読者の現在の位置を確認しているので、実際に次のキャラクターがどうなっているかを確認しているわけではないので、そのように使用する必要はないと思います。

41

バイナリデータを操作するときにEOFをチェックするより正確な方法があります。PeekCharアプローチに伴うエンコードの問題をすべて回避し、必要なことを正確に実行します。リーダーの位置がファイルの最後にあるかどうかを確認します。

while (inFile.BaseStream.Position != inFile.BaseStream.Length)
{
   ...
}
81

これは私のために働く:

using (BinaryReader br = new BinaryReader(File.Open(fileName,   
FileMode.Open))) {
            //int pos = 0;
            //int length = (int)br.BaseStream.Length;
            while (br.BaseStream.Position != br.BaseStream.Length) {
                string nume = br.ReadString ();
                string prenume = br.ReadString ();
                Persoana p = new Persoana (nume, prenume);
                myArrayList.Add (p);
                Console.WriteLine ("ADAUGAT XXX: "+ p.ToString());
                //pos++;
            }
        }
3
user1803917

それを カスタム拡張メソッド にラップすると、欠落しているEOFメソッドを追加することでBinaryReaderクラスを拡張します。

public static class StreamEOF {

    public static bool EOF( this BinaryReader binaryReader ) {
        var bs = binaryReader.BaseStream;
        return ( bs.Position == bs.Length);
    }
}

だから今、あなたはただ書くことができます:

while (!infile.EOF()) {
   // Read....
}

:) ...次のような場所にinfileを作成したと仮定します:

var infile= new BinaryReader();

注: var は暗黙的な入力です。それを見つけてうれしい-それは、C#でうまくスタイル設定されたコードのための他のパズルのピースです。 :D

3
Un Peu

私の提案を追加します:BinaryReaderの「エンコード」部分が必要ない場合(したがって、さまざまなReadChar/ReadChars/ReadStringを使用しない)、スローしないエンコーダーを使用できます。常に1バイトにつき1バイトです。 Encoding.GetEncoding("iso-8859-1")はこれに最適です。 BinaryReaderコンストラクターのパラメーターとして渡します。 iso-8859-1エンコードは、Unicodeの最初の256文字すべてを1:1でマップする1文字あたり1バイトのエンコードです(したがって、byte 254はchar 254です。 )

1
xanatos