Це дійсно залежить від того, можна довіряти чи ні 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
буде продовжуватись до кінця потоку чи вказаного Вами розміру, але Ви все ще повинні знати розмір, з якого слід почати.
Вищеописаний метод буде постійно читати (і копіювати в a MemoryStream
), поки у нього не закінчиться даних. Потім він просить MemoryStream
повернути копію даних у масив. Якщо ви знаєте розмір, з якого слід почати - або вважаєте, що знаєте розмір, не маючи впевненості - ви можете сконструювати MemoryStream
цей розмір для початку. Так само ви можете поставити чек у кінці, і якщо довжина потоку того ж розміру, що і буфер (повертається MemoryStream.GetBuffer
), ви можете просто повернути буфер. Отже, наведений вище код не зовсім оптимізований, але принаймні буде правильним. Він не несе відповідальності за закриття потоку - абонент повинен це зробити.
Дивіться цю статтю для отримання додаткової інформації (та альтернативної реалізації).