Этот ответ запоздал и, возможно, больше не относится к вам, но может пригодиться кому-то еще, кто сталкивается с этой проблемой.
Моя проблема связана с файлами PPM , которые имеют аналогичный формат:
- ASCII текст в начале
- Двоичные байты для остальной части файла
Проблема, с которой я столкнулся, заключалась в том, что класс StreamReader
не способен читать данные по одному байту за раз без буферизации материала. В некоторых случаях это приводило к неожиданным результатам, поскольку метод Read()
читает один символ, а не один байт.
Мое решение было написать обертку вокруг потока, которая будет читать байты по одному. Обертка имеет 2 важных метода, ReadLine()
и Read()
.
Эти 2 метода позволяют мне читать строки ASCII потока без буферизации, а затем читать по одному байту за раз для остальной части потока. Возможно, вам придется внести некоторые изменения в соответствии с вашими потребностями.
class UnbufferedStreamReader: TextReader
{
Stream s;
public UnbufferedStreamReader(string path)
{
s = new FileStream(path, FileMode.Open);
}
public UnbufferedStreamReader(Stream stream)
{
s = stream;
}
// This method assumes lines end with a line feed.
// You may need to modify this method if your stream
// follows the Windows convention of \r\n or some other
// convention that isn't just \n
public override string ReadLine()
{
List<byte> bytes = new List<byte>();
int current;
while ((current = Read()) != -1 && current != (int)'\n')
{
byte b = (byte)current;
bytes.Add(b);
}
return Encoding.ASCII.GetString(bytes.ToArray());
}
// Read works differently than the `Read()` method of a
// TextReader. It reads the next BYTE rather than the next character
public override int Read()
{
return s.ReadByte();
}
public override void Close()
{
s.Close();
}
protected override void Dispose(bool disposing)
{
s.Dispose();
}
public override int Peek()
{
throw new NotImplementedException();
}
public override int Read(char[] buffer, int index, int count)
{
throw new NotImplementedException();
}
public override int ReadBlock(char[] buffer, int index, int count)
{
throw new NotImplementedException();
}
public override string ReadToEnd()
{
throw new NotImplementedException();
}
}