Это действительно зависит от того, можете ли вы доверять 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), вы можете просто вернуть буфер. Таким образом, приведенный выше код не совсем оптимизирован, но, по крайней мере, будет правильным. Он не несет ответственности за закрытие потока - вызывающий должен это сделать.
См. this article для получения дополнительной информации (и альтернативной реализации).
Конечно, другой вопрос: * должен * создать байт [] из потока ... для больших данных предпочтительнее обрабатывать поток, как, ну, поток! – 2008-10-21 13:57:27