Realmente depende se você pode ou não confiar s.Length
. Para muitos fluxos, você simplesmente não sabe quantos dados haverá. Nesses casos - e antes do .NET 4 - eu usaria código como este:
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();
}
}
Com o .NET 4 e superior, eu usaria Stream.CopyTo
, que é basicamente equivalente ao loop no meu código - crie a MemoryStream
chamada, stream.CopyTo(ms)
e depois retorne ms.ToArray()
. Tarefa concluída.
Talvez eu devesse explicar por que minha resposta é mais longa que as outras. Stream.Read
não garante que ele leia tudo o que for solicitado. Se você estiver lendo de um fluxo de rede, por exemplo, ele poderá ler o valor de um pacote e retornar, mesmo que em breve haja mais dados. BinaryReader.Read
continuará até o final do fluxo ou o tamanho especificado, mas você ainda precisa saber o tamanho para começar.
O método acima continuará lendo (e copiando em a MemoryStream
) até ficar sem dados. Em seguida, solicita MemoryStream
que você retorne uma cópia dos dados em uma matriz. Se você sabe o tamanho para começar - ou acha que sabe o tamanho, sem ter certeza -, você pode MemoryStream
criar o tamanho que seja para começar. Da mesma forma, você pode marcar no final e, se o comprimento do fluxo for do mesmo tamanho do buffer (retornado por MemoryStream.GetBuffer
), basta retornar o buffer. Portanto, o código acima não é totalmente otimizado, mas pelo menos estará correto. Ele não assume nenhuma responsabilidade por fechar o fluxo - o chamador deve fazer isso.
Consulte este artigo para obter mais informações (e uma implementação alternativa).