Это действительно зависит от того, можете ли вы доверять s.Length
. Для многих потоков вы просто не знаете, сколько будет данных. В таких случаях - и до .NET 4 - я бы использовал такой код:
public static byte[] ReadFully(Stream input)
{
byte[] buffer = new byte[16*1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
В .NET 4 и выше я бы использовал Stream.CopyTo
, что в основном эквивалентно циклу в моем коде - создайте MemoryStream
, вызовите stream.CopyTo(ms)
и затем верните ms.ToArray()
. Работа выполнена.
Возможно, мне следует объяснить, почему мой ответ длиннее других. Stream.Read
не гарантирует, что он будет читать все, о чем он просил. Например, если вы читаете из сетевого потока, он может прочитать ценность одного пакета и затем вернуться, даже если скоро будет больше данных. BinaryReader.Read
будет продолжаться до конца потока или указанного вами размера, но вы все равно должны знать размер для начала.
Вышеуказанный метод будет продолжать читать (и копировать в MemoryStream
), пока не закончатся данные. Затем он MemoryStream
просит вернуть копию данных в массиве. Если вы знаете размер для начала - или думаете , вы знаете размер, не будучи уверенным - вы можете создать MemoryStream
для того, чтобы начать с этого размера. Точно так же вы можете поставить проверку в конце, и если длина потока равна размеру буфера (возвращается MemoryStream.GetBuffer
), то вы можете просто вернуть буфер. Таким образом, приведенный выше код не совсем оптимизирован, но, по крайней мере, будет правильным. Он не несет никакой ответственности за закрытие потока - вызывающий должен сделать это.
См. в этой статье для получения дополнительной информации (и альтернативной реализации).