C# 检查文件的二进制读取器结束

本文关键字:读取 结束 二进制 检查 文件 | 更新日期: 2023-09-27 18:36:28

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

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

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

未处理的异常:系统参数异常:输出字符缓冲区太 small 以包含解码的字符,编码"Unicode (UTF-8)"回退"系统"m.Text.DecoderReplacementFallback'.参数名称:字符   at System.Text.Encoding.ThrowCharsOverflow()   at System.Text.Encoding.ThrowCharsOverflow(DecoderNLS decoder, Boolean nothing解码)   at System.Text.UTF8Encoding.GetChars(Byte* bytes, Int32 byteCount, Char* chars, 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 byteCount, char[] chars, Int32 charIndex, Boolean flush)   at System.Text.DecoderNLS.GetChars(Byte[] bytes, Int32 byteIndex, Int32 byteCount, char[] chars, Int32 charIndex)   at System.IO.BinaryReader.InternalReadOneChar()   at System.IO.BinaryReader.PeekChar()

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

C# 检查文件的二进制读取器结束

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

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

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

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

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

这对我来说是:

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++;
            }
        }

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