Есть ли какая-либо причина, по которой GZipStream.Read будет возвращать меньше числа запрошенных байтов? - PullRequest
0 голосов
/ 17 февраля 2012

В документах написано :

Возвращаемое значение:
Общее количество байтов, считанных в буфер. Это может быть меньше количества запрошенных байтов, если столько байтов в данный момент недоступно, или ноль (0), если достигнут конец потока.

Но почему байты «не будут доступны» при чтении с диска?


Позвольте мне немного уточнить:

  1. Я читаю с диска (базовый тип FileStream)
  2. Осталось как минимум N байтов, которые нужно прочитать (до EOF)
  3. прошу прочитать N байт

Будет ли возвращаемое значение / количество прочитанных байтов когда-либо меньше N в этом сценарии?

Ответы [ 4 ]

2 голосов
/ 17 февраля 2012

В ответ на ваш отредактированный вопрос:

Будет ли возвращаемое значение / число прочитанных байтов когда-либо меньше N в этом сценарии?

Я думаю, что вам нужноспросить эксперта по аппаратному обеспечению, и я полагаю, что это не тот форум, чтобы привлечь внимание такого человека.,Это всего лишь предположение:

Я думаю , что при чтении с диска единственная причина, по которой вы получаете меньше байтов, чем запрашиваете, заключается в том, что поток исчерпал байты длядать вам.Тем не менее, вполне возможно, что у вас может быть ситуация, подобная сетевому потоку, когда ваша программа читает байты быстрее, чем оборудование может их предоставить.В этом случае метод Read предположительно заполнит буфер только частично, а затем вернется.

Очевидно, что ответ на вопрос зависит от того, может ли такая ситуация возникнуть.Я думаю ответ "нет".Я, конечно, никогда не видел контрпример.Но было бы ошибкой писать код в зависимости от этого предположения.

Подумайте: даже если вы сможете проверить спецификации всего оборудования, на котором будет работать ваш код, и доказать, что буфер всегда будет полностью заполнен, покаДостигнут конец потока, невозможно сказать, какой новый диск кто-то может установить на машину в будущем, который может вести себя по-другому.Гораздо проще просто обрабатывать все потоки одинаково и выполнять скромный объем работы, необходимый для обработки вероятности того, что буфер вернется не полностью заполненным.

1 голос
/ 31 июля 2014

Мое решение:

public static class StreamExt
{
    public static void ReadBytes(this Stream stream, byte[] buffer, int offset, int count)
    {
        int totalBytesRead = 0;
        while (totalBytesRead < count)
        {
            int bytesRead = stream.Read(buffer, offset + totalBytesRead, count - totalBytesRead);
            if (bytesRead == 0) throw new IOException("Premature end of stream");
            totalBytesRead += bytesRead;
        } 
    }
}

Использование этого метода должно безопасно считывать все запрошенные вами байты.

1 голос
/ 17 февраля 2012

Потоки сжатия являются потоком-оберткой, поэтому их поведение зависит от поведения основного потока.В результате он имеет то же ограничение, что и общий поток, «может вернуть меньше байтов, чем запрошено».

Что касается потенциальных причин ( см. Также предоставлено Lloyd)

  • EOF достигнут при последнем чтении
  • В потоке сети еще нет данных
  • Пользовательский страм решил вернуть данные в виде фрагментов фиксированного размера (совершенно нормально).
1 голос
/ 17 февраля 2012

Stream.Read требует, чтобы вы предварительно распределили пространство для чтения, и если вы выделите больше места, чем может быть прочитано из потока, то возвращаемое значение - это способ сообщить вам, сколько из этого было использовано.

Примите во внимание следующее:

Если вы выделите буфер, скажем, 4096 байт, а значение EOF будет достигнуто в 2046, тогда возвращаемое значение будет только 2046. Это позволяет вам знать, какбольшая часть вашего буфера заполнена при возврате.

...