C# проверка конца двоичного считывателя файла

Я искал способ проверить, достиг ли я конца файла для моего двоичного считывателя, и одним из предложений было использовать 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()

4 ответов


существует более точный способ проверки EOF при работе с двоичными данными. Это позволяет избежать всех проблем кодирования, которые приходят с PeekChar подход и делает именно то, что необходимо: проверить, находится ли позиция читателя в конце файла или нет.

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

обернув его в Пользовательский Метод Расширения это расширит BinaryReader класс, добавив отсутствующий метод EOF.

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 все первые 256 символов Юникода (так что byte 254-это char 254 для пример)