Itu benar-benar tergantung pada apakah Anda bisa percaya atau tidak s.Length
. Untuk banyak aliran, Anda tidak tahu berapa banyak data yang akan ada. Dalam kasus seperti itu - dan sebelum .NET 4 - Saya akan menggunakan kode seperti ini:
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();
}
}
Dengan .NET 4 dan di atasnya, saya akan menggunakan Stream.CopyTo
, yang pada dasarnya setara dengan loop dalam kode saya - buat MemoryStream
, panggil stream.CopyTo(ms)
dan kembalilah ms.ToArray()
. Pekerjaan selesai.
Saya mungkin harus menjelaskan mengapa jawaban saya lebih panjang dari yang lain. Stream.Read
tidak menjamin bahwa itu akan membaca semua yang diminta. Jika Anda membaca dari aliran jaringan, misalnya, ia mungkin membaca nilai satu paket dan kemudian kembali, bahkan jika akan ada lebih banyak data segera. BinaryReader.Read
akan terus berjalan hingga akhir streaming atau ukuran yang Anda tentukan, tetapi Anda masih harus tahu ukuran untuk memulai.
Metode di atas akan terus membaca (dan menyalin ke a MemoryStream
) sampai kehabisan data. Kemudian meminta MemoryStream
untuk mengembalikan salinan data dalam array. Jika Anda tahu ukuran untuk memulai - atau berpikir Anda tahu ukurannya, tanpa yakin - Anda bisa membuat MemoryStream
menjadi ukuran itu. Demikian juga Anda dapat memberi tanda centang di akhir, dan jika panjang aliran adalah ukuran yang sama dengan buffer (dikembalikan oleh MemoryStream.GetBuffer
) maka Anda bisa mengembalikan buffer. Jadi kode di atas tidak cukup dioptimalkan, tetapi setidaknya akan benar. Itu tidak memikul tanggung jawab untuk menutup aliran - penelepon harus melakukan itu.
Lihat artikel ini untuk info lebih lanjut (dan implementasi alternatif).