#c#
Вопрос:
Я написал метод расширения следующим образом
public static void ReadBlock(this Stream stream, Action<string> action, int bufferSize = 8192)
{
var buffer = new byte[bufferSize];
while (true)
{
var count = stream.Read(buffer, 0, bufferSize);
if (count == 0) break;
var text = Encoding.ASCII.GetString(buffer);
action(text);
}
}
Проблема, с которой я сталкиваюсь, заключается в том, что последний блок, который часто меньше размера буфера, не считывается.
и код снова возвращает блок n-1 (последний буфер).
Может ли кто-нибудь помочь мне правильно прочитать поток блок за блоком в зависимости от размера буфера?
Комментарии:
1. Вы захотите использовать
Encoding.ASCII.GetString(buffer, 0, count)
Ответ №1:
Проблема в том, что вы не указываете Encoding.GetString
, сколько буфера нужно прочитать.
Если вы читаете из потока и bufferSize
доступны байты, то он заполнит буфер этими байтами.
Если вы читаете из потока и доступно меньше bufferSize
байтов, он запишет эти байты в начало буфера, но не коснется остальной части буфера. Это означает, что буфер содержит count
байты новых данных, а остальное заполнено данными из вашего последнего чтения.
Однако Encoding.GetString
он этого не знает и просто обработает весь буфер. Что может быть смесью старых и новых данных.
Решение, конечно, состоит в том, чтобы указать Encoding.GetString
, сколько буфера нужно прочитать:
var text = Encoding.ASCII.GetString(buffer, 0, count);
Обратите внимание, что этот подход будет работать только с ASCII или другими кодировками, в которых используется только 1 байт на символ. Если вы перейдете на UTF-8 или UTF-16 и т. Д., Тогда все пойдет ужасно неправильно. В этом случае вам понадобится декодер.