Ответ 1
Этот ответ опаздывает и, возможно, больше не относится к вам, но может оказаться полезным для кого-то другого, кто сталкивается с этой проблемой.
Моя проблема связана с 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();
}
}