Это действительно зависит от того, можете ли вы доверять или нет 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
), то вы можете просто вернуть буфер. Таким образом, приведенный выше код не совсем оптимизирован, но, по крайней мере, будет правильным. Он не несет никакой ответственности за закрытие потока - вызывающий должен сделать это.
Смотрите эту статью для получения дополнительной информации (и альтернативной реализации).