To naprawdę zależy od tego, czy możesz zaufać s.Length
. W przypadku wielu strumieni po prostu nie wiesz, ile będzie danych. W takich przypadkach - i wcześniej .NET 4 - użyłbym takiego kodu:
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();
}
}
W .NET 4 i nowszych użyłbym Stream.CopyTo
, co w zasadzie jest równoważne pętli w moim kodzie - utwórz MemoryStream
, wywołaj, stream.CopyTo(ms)
a następnie zwróć ms.ToArray()
. Zadanie wykonane.
Być może powinienem wyjaśnić, dlaczego moja odpowiedź jest dłuższa niż inne. Stream.Read
nie gwarantuje, że przeczyta wszystko, o co prosi. Jeśli na przykład czytasz ze strumienia sieciowego, może on odczytać wartość jednego pakietu, a następnie powrócić, nawet jeśli wkrótce będzie więcej danych. BinaryReader.Read
będzie działać do końca strumienia lub określonego rozmiaru, ale nadal musisz znać rozmiar, aby zacząć.
Powyższa metoda będzie odczytywać (i kopiować do a MemoryStream
), dopóki nie zabraknie danych. Następnie prosi MemoryStream
o zwrócenie kopii danych w tablicy. Jeśli znasz rozmiar na początek - lub uważasz, że znasz rozmiar, bez pewności - możesz skonstruować MemoryStream
taki rozmiar, aby zacząć. Podobnie możesz umieścić czek na końcu, a jeśli długość strumienia jest tego samego rozmiaru co bufor (zwracany przez MemoryStream.GetBuffer
), możesz po prostu zwrócić bufor. Tak więc powyższy kod nie jest do końca zoptymalizowany, ale przynajmniej będzie poprawny. Nie ponosi żadnej odpowiedzialności za zamknięcie strumienia - dzwoniący powinien to zrobić.
Zobacz ten artykuł, aby uzyskać więcej informacji (i alternatywną implementację).