入力ストリームからバイト配列を作成するための推奨される方法は何ですか?
これが .NET 3.5 を使用した現在のソリューションです。
Stream s;
byte[] b;
using (BinaryReader br = new BinaryReader(s))
{
b = br.ReadBytes((int)s.Length);
}
ストリームのチャンクを読み書きする方がまだ良い考えでしょうか?
ベストアンサー1
それは本当に信頼できるかどうかによりますs.Length
。多くのストリームでは、データの量がわかりません。そのような場合、および .NET 4 より前のバージョンでは、次のようなコードを使用します。
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();
}
}
.NET 4以降では、Stream.CopyTo
は、基本的に私のコード内のループと同等です。 を作成しMemoryStream
、 を呼び出してstream.CopyTo(ms)
、 を返しますms.ToArray()
。これで完了です。
私の回答が他の回答よりも長い理由を説明する必要があるかもしれません。Stream.Read
要求されたすべてのデータを読み取ることを保証するものではありません。たとえば、ネットワーク ストリームから読み取る場合、すぐにさらにデータがある場合でも、1 つのパケット分を読み取ってから戻ることがあります。BinaryReader.Read
ストリームの終わりまたは指定したサイズまで継続されますが、開始するサイズを知っておく必要があります。
MemoryStream
上記のメソッドは、データがなくなるまで読み取り(および へのコピー)を続けます。その後、MemoryStream
にデータのコピーを配列で返すように要求します。開始時のサイズがわかっている場合、または確信がなくてもサイズがわかっていると思われる場合MemoryStream
は、 をそのサイズで開始するように構築できます。同様に、最後にチェックを入れて、ストリームの長さがバッファ( によって返される)と同じサイズであるかどうかを確認することもできます。MemoryStream.GetBuffer
) バッファを返すだけで済みます。したがって、上記のコードは完全に最適化されているわけではありませんが、少なくとも正しいものになります。ストリームを閉じる責任は負いません。呼び出し側がそれを行う必要があります。
見るこの記事詳細情報(および代替実装)については、こちらをご覧ください。