Nó thực sự phụ thuộc vào việc bạn có thể tin tưởng hay không s.Length
. Đối với nhiều luồng, bạn không biết sẽ có bao nhiêu dữ liệu. Trong những trường hợp như vậy - và trước .NET 4 - Tôi sẽ sử dụng mã như thế này:
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();
}
}
Với .NET 4 trở lên, tôi sẽ sử dụng Stream.CopyTo
, về cơ bản tương đương với vòng lặp trong mã của tôi - tạo MemoryStream
, gọi stream.CopyTo(ms)
và sau đó trả về ms.ToArray()
. Công việc hoàn thành.
Tôi có lẽ nên giải thích tại sao câu trả lời của tôi dài hơn những người khác. Stream.Read
không đảm bảo rằng nó sẽ đọc mọi thứ nó yêu cầu. Ví dụ: nếu bạn đang đọc từ một luồng mạng, nó có thể đọc giá trị của một gói và sau đó quay lại, ngay cả khi sẽ có nhiều dữ liệu sớm hơn. BinaryReader.Read
sẽ tiếp tục cho đến khi kết thúc luồng hoặc kích thước được chỉ định của bạn, nhưng bạn vẫn phải biết kích thước để bắt đầu.
Phương pháp trên sẽ tiếp tục đọc (và sao chép vào a MemoryStream
) cho đến khi hết dữ liệu. Sau đó nó yêu cầu MemoryStream
trả về một bản sao của dữ liệu trong một mảng. Nếu bạn biết kích thước để bắt đầu - hoặc nghĩ rằng bạn biết kích thước, mà không chắc chắn - bạn có thể xây dựng MemoryStream
kích thước đó để bắt đầu. Tương tự như vậy, bạn có thể đặt một kiểm tra ở cuối và nếu độ dài của luồng có cùng kích thước với bộ đệm (được trả về bởi MemoryStream.GetBuffer
) thì bạn có thể trả về bộ đệm. Vì vậy, đoạn mã trên không được tối ưu hóa hoàn toàn, nhưng ít nhất sẽ đúng. Nó không chịu bất kỳ trách nhiệm nào trong việc đóng luồng - người gọi nên làm điều đó.
Xem bài viết này để biết thêm thông tin (và thực hiện thay thế).