Dipende davvero dalla fiducia s.Length
. Per molti stream, semplicemente non sai quanti dati ci saranno. In questi casi - e prima di .NET 4 - utilizzerei il codice in questo modo:
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();
}
}
Con .NET 4 e versioni successive, utilizzerei Stream.CopyTo
, che è sostanzialmente equivalente al ciclo nel mio codice: crea MemoryStream
, chiama stream.CopyTo(ms)
e poi ritorna ms.ToArray()
. Lavoro fatto.
Dovrei forse spiegare perché la mia risposta è più lunga delle altre. Stream.Read
non garantisce che leggerà tutto ciò che viene richiesto. Se stai leggendo da un flusso di rete, ad esempio, potrebbe leggere il valore di un pacchetto e quindi restituirlo, anche se presto ci saranno più dati. BinaryReader.Read
continuerà fino alla fine dello stream o alla dimensione specificata, ma devi comunque conoscere la dimensione con cui iniziare.
Il metodo sopra continuerà a leggere (e copiare in a MemoryStream
) fino a quando non si esauriscono i dati. Quindi chiede MemoryStream
di restituire una copia dei dati in un array. Se conosci le dimensioni con cui iniziare - o pensi di conoscerne le dimensioni, senza essere sicuro - puoi costruirle MemoryStream
per iniziare con quelle dimensioni. Allo stesso modo puoi mettere un segno di spunta alla fine e se la lunghezza del flusso ha le stesse dimensioni del buffer (restituito da MemoryStream.GetBuffer
), puoi semplicemente restituire il buffer. Quindi il codice sopra non è del tutto ottimizzato, ma almeno sarà corretto. Non si assume alcuna responsabilità per la chiusura del flusso - il chiamante dovrebbe farlo.
Vedi questo articolo per maggiori informazioni (e un'implementazione alternativa).