NetworkStream читает меньше байтов, чем ожидалось

Если messageBytes.Length достаточно велик (скажем, около 30 000), то stream.Read читает меньше байтов, чем ожидалось.

Using stream As New Net.Sockets.NetworkStream(socket)
    networkStream.Read(messageBytes, 0, messageBytes.Length)
End Using

Документация в MSDN заявляет об этом в разделе Примечания

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

Я смог прочитать его в цикле while, читая один байт, пока не будет достигнута желаемая позиция, например

Dim position = 0
While position < messageBytes.Length
    stream.Read(messageBytes, position, 1)
    position += 1
End While

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


person Anshuman Chatterjee    schedule 28.11.2015    source источник


Ответы (1)


Он блокируется до тех пор, пока не будут прочитаны некоторые данные. Это очень важно, если вы обрабатываете данные по мере их поступления. Например, если вы собираетесь записать данные в файл, вы можете начать запись немедленно, а не ждать, пока все данные будут загружены.

Это также позволяет обрабатывать больше данных, чем умещается в памяти.

Однако вам не нужно читать его байт за байтом, то есть:

public byte[] ReadFixedLength(this Stream stream, int length)
{
    byte[] buffer = new byte[length];
    int offset = 0;
    while (length > 0)
    {
        int read = stream.Read(buffer, offset, length);
        if (read == 0)
        {
            throw new EndOfStreamException();
        }

        offset += read;
        length -= read;
    }

    return buffer;
}
person C.Evenhuis    schedule 28.11.2015
comment
Следует отметить, что вопрос находится в VB.NET, и что предоставленный вами метод может быть гораздо более чистым, позвольте мне отредактировать его. - person Camilo Terevinto; 28.11.2015