Как прочитать последний блок потока.Читать

#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 и т. Д., Тогда все пойдет ужасно неправильно. В этом случае вам понадобится декодер.