C#检查二进制阅读器文件结尾

时间:2012-06-08 03:48:49

标签: c# binaryfiles binaryreader

我正在寻找一种检查我是否已经到达二进制阅读器文件末尾的方法,其中一条建议就是使用PeekChar

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

然而,看起来我遇到了一个问题

Unhandled Exception: System.ArgumentException: The output char buffer is too sma
ll to contain the decoded characters, encoding 'Unicode (UTF-8)' fallback 'Syste
m.Text.DecoderReplacementFallback'.
Parameter name: 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.InternalReadOneChar()
   at System.IO.BinaryReader.PeekChar()

所以也许PeekChar不是最好的方法,我认为它甚至不应该以那种方式使用,因为我正在检查读者的当前位置,而不是下一个字符应该是什么是

5 个答案:

答案 0 :(得分:76)

使用二进制数据时,有一种更准确的方法来检查EOF。它避免了PeekChar方法带来的所有编码问题并完全满足需要:检查阅读器的位置是否位于文件的末尾。

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

答案 1 :(得分:3)

将其包装到Custom Extension Method中,通过添加缺少的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

答案 2 :(得分:3)

这项工作适合我:

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 :(得分:1)

我会添加我的建议:如果您不需要&#34;编码&#34; BinaryReader的一部分(所以你不要使用各种ReadChar / ReadChars / ReadString)然后你可以使用一个不会抛出的编码器,它总是每个字符一个字节。 Encoding.GetEncoding("iso-8859-1")非常适合这一点。您将其作为BinaryReader构造函数的参数传递。 iso-8859-1编码是一个每字节一个字节的编码,它以1:1的方式映射Unicode的前256个字符(例如,byte 254是char 254 <) / p>

答案 4 :(得分:1)

我建议与@MxLDevs非常相似,但是使用'<'运算符而不是'!='运算符。由于可以将Position设置为任何您想要的值(在很长的范围内),这将阻止任何尝试通过循环访问无效文件Position的尝试。

while (inFile.BaseStream.Position < inFile.BaseStream.Length)
{
   ...
}