Проверка С# для двоичного считывания конца файла
Я искал способ проверить, достиг ли я конца файла для моего бинарного считывателя, и одно предложение заключалось в том, чтобы использовать 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 - это не лучший способ сделать это, и я не думаю, что его даже следует использовать таким образом, потому что я проверяю текущую позицию моего читателя и не совсем то, что следующий символ должен быть.
Ответы
Ответ 1
Существует более точный способ проверки EOF при работе с двоичными данными. Он избегает всех проблем с кодировкой, которые входят в подход PeekChar
, и делает именно то, что необходимо: чтобы проверить, находится ли позиция читателя в конце файла или нет.
while (inFile.BaseStream.Position != inFile.BaseStream.Length)
{
...
}
Ответ 2
Включение его в Пользовательский метод расширения, который расширит класс 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 - это неявное типирование.
С удовольствием нашел это - это еще одна головоломка для хорошо оформленного кода на С#.: D
Ответ 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++;
}
}
Ответ 4
Я добавлю свое предложение: если вам не нужна "кодировка" части BinaryReader (поэтому вы не используете различные ReadChar/ReadChars/ReadString), вы можете использовать кодировщик, который никогда не будет throw, и это всегда один байт за char. Encoding.GetEncoding("iso-8859-1")
идеально подходит для этого. Вы передаете его как параметр конструктора BinaryReader
. Кодировка iso-8859-1 представляет собой кодировку с одним байтом на символ, которая отображает 1:1 все первые 256 символов Unicode (поэтому byte
254 является char
254, например)