54

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

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

但是,看起来我遇到了问题

未处理的异常:System.ArgumentException:输出字符缓冲区太小
ll 包含解码后的字符,编码 'Unicode (UTF-8)' fallback 'Syste
m.Text.DecoderReplacementFallback'。
参数名称:字符
   在 System.Text.Encoding.ThrowCharsOverflow()
   在 System.Text.Encoding.ThrowCharsOverflow(DecoderNLS 解码器,布尔无
g解码)
   在 System.Text.UTF8Encoding.GetChars(Byte* 字节,Int32 byteCount,Char* char
s, Int32 charCount, DecoderNLS baseDecoder)
   在 System.Text.DecoderNLS.GetChars(Byte* bytes, Int32 byteCount, Char* chars,
 Int32 charCount,布尔刷新)
   在 System.Text.DecoderNLS.GetChars(Byte[] bytes, Int32 byteIndex, Int32 byteC
数量,Char[] 字符,Int32 charIndex,布尔刷新)
   在 System.Text.DecoderNLS.GetChars(Byte[] bytes, Int32 byteIndex, Int32 byteC
数量,Char[] 字符,Int32 字符索引)
   在 System.IO.BinaryReader.InternalReadOneChar()
   在 System.IO.BinaryReader.PeekChar()

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

4

5 回答 5

101

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

while (inFile.BaseStream.Position != inFile.BaseStream.Length)
{
   ...
}
于 2013-08-06T15:12:37.217 回答
5

将其包装到自定义扩展方法中,该方法将通过添加缺少的 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

于 2015-10-22T03:00:03.217 回答
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++;
            }
        }
于 2016-07-26T16:19:25.907 回答
3

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

while (inFile.BaseStream.Position < inFile.BaseStream.Length)
{
   ...
}
于 2020-08-21T10:54:42.447 回答
2

我将添加我的建议:如果您不需要 BinaryReader 的“编码”部分(因此您不使用各种 ReadChar/ReadChars/ReadString),那么您可以使用永远不会抛出的编码器始终为每个字符一个字节。Encoding.GetEncoding("iso-8859-1")非常适合这个。您将它作为BinaryReader构造函数的参数传递。iso-8859-1 编码是每个字符一个字节的编码,它以 1:1 的比例映射 Unicode 的所有前 256 个字符(例如,byte254 就是char254)

于 2017-04-04T12:53:44.793 回答