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

C#检查二进制读取器文件结尾,c#,binaryfiles,binaryreader,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 (UT

我正在寻找一种方法来检查我是否已经到达二进制读取器的文件末尾,其中一个建议是使用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() 未处理的异常:System.ArgumentException:输出字符缓冲区太小 ll将包含解码字符,编码为“Unicode(UTF-8)”的“回退”系统 m、 Text.DecoderReplacementFallback'。 参数名称:chars 位于System.Text.Encoding.ThrowCharsOverflow()处 在System.Text.Encoding.ThrowCharsOverflow(DecoderNLS decoder,布尔nothin GDECODE) 在System.Text.UTF8Encoding.GetChars(字节*字节,Int32字节计数,字符*字符 s、 Int32字符数,解码器(基本解码器) 在System.Text.DecoderNLS.GetChars(字节*字节,Int32字节计数,字符*字符, Int32字符数,布尔刷新) 位于System.Text.DecoderNLS.GetChars(字节[]字节,Int32字节索引,Int32字节索引 ount,Char[]chars,Int32 charIndex,布尔刷新) 位于System.Text.DecoderNLS.GetChars(字节[]字节,Int32字节索引,Int32字节索引 count,Char[]chars,Int32 charIndex) 位于System.IO.BinaryReader.InternalReadOneChar()处 在System.IO.BinaryReader.PeekChar()中
因此,PeekChar可能不是最好的方法,我甚至不认为应该这样使用,因为我正在检查阅读器的当前位置,而不是下一个字符应该是什么。

在处理二进制数据时,有一种更准确的方法来检查EOF。它避免了
PeekChar
方法所带来的所有编码问题,并准确地执行了所需的操作:检查读取器的位置是否在文件的末尾

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....
}
:) ... 假设您已经创建了类似以下内容的infle

var infile= new BinaryReader();
注意:是隐式类型。
很高兴找到它-这是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),那么您可以使用一个永远不会抛出的编码器,并且始终是每个字符一个字节<代码>编码。GetEncoding(“iso-8859-1”)非常适合于此。您可以将其作为
BinaryReader
构造函数的参数传递。iso-8859-1编码是每个字符一个字节的编码,它将Unicode的所有前256个字符按1:1进行映射(例如,
字节
254就是
字符
254)

我建议与@MxLDevs非常类似,但使用“使用流阅读器(字符流)”读取文本文件。如果要读取文件,我建议您使用BinaryReader.ReadBytes(nBytes_to_be__read)。根据您的特定代码以及文件访问是否共享,您还可以将流的.Length属性缓存到局部变量,这将进一步优化和提高性能。请注意,
位置
长度
类的属性,而不是方法。除非您使用这些相同的名称定义了扩展方法,否则方法调用语法将无法编译。谢谢,我不确定以前为什么将它们作为方法编写。这仅在底层流支持查找时才有效。@Paul
PeekChar
,所以这并不是真正的区别:)取决于底层流,调用BaseStream.Length可能非常慢<例如,代码>文件流每次都将调用Win32.GetFileSize()。如果您知道长度不会改变,那么您可能希望首先缓存它(例如:在本地变量中),这是错误的,非常错误的。应该返回(bs.Position==bs.Length);还有!其中一条注释解决了一个问题,即不支持查找的流不支持直接检查流的长度。我想在这种情况下,这可能会解决那个问题。@MxyL不,它不会解决那个问题。
PeekChar()
执行一个
Read()
,然后使用
位置
回滚
Read()
。为清楚起见,建议使用什么方法检查带有特定编码的文件结尾?
while (inFile.BaseStream.Position < inFile.BaseStream.Length)
{
   ...
}