web-dev-qa-db-ja.com

(すべてのバイトの)BinaryReaderを消費するエレガントな方法ですか?

StreamReader.ReadToEndメソッドをBinaryReaderでエミュレートするエレガントな方法はありますか?おそらくすべてのバイトをバイト配列に入れますか?

私はこれをします:

read1.ReadBytes((int)read1.BaseStream.Length);

...しかし、もっと良い方法がなければなりません。

61
SamFisher83

単純に:

byte[] allData = read1.ReadBytes(int.MaxValue);

documentation は、ストリームの終わりに達するまですべてのバイトを読み取ることを示します。


更新

これはエレガントに思えますが、ドキュメントではこれが機能することが示されているようですが、実際の実装(.NET 2、3.5、および4でチェック)が割り当てられますデータ用のフルサイズのバイト配列。これにより、おそらく32ビットシステムでOutOfMemoryExceptionが発生します。

したがって、実際にはエレガントな方法はありません

代わりに、@ ianoの回答の次のバリエーションをお勧めします。このバリアントは、.NET 4に依存しません。
BinaryReader(またはStream、コードはどちらも同じです)の拡張メソッドを作成します。

public static byte[] ReadAllBytes(this BinaryReader reader)
{
    const int bufferSize = 4096;
    using (var ms = new MemoryStream())
    {
        byte[] buffer = new byte[bufferSize];
        int count;
        while ((count = reader.Read(buffer, 0, buffer.Length)) != 0)
            ms.Write(buffer, 0, count);
        return ms.ToArray();
    }

}
90
Scott Rippey

BinaryReaderでこれを行うeasyの方法はありません。事前に読み取る必要があるカウントがわからない場合は、MemoryStreamを使用することをお勧めします。

_public byte[] ReadAllBytes(Stream stream)
{
    using (var ms = new MemoryStream())
    {
        stream.CopyTo(ms);
        return ms.ToArray();
    }
}
_

ToArray()を呼び出すときに追加のコピーを避けるには、代わりにGetBuffer()を介してPositionとバッファを返すことができます。

69
iano

ストリームのコンテンツを別のストリームにコピーするために、ファイルの最後に到達するまで「いくつかの」バイトの読み取りを解決しました。

private const int READ_BUFFER_SIZE = 1024;
using (BinaryReader reader = new BinaryReader(responseStream))
{
    using (BinaryWriter writer = new BinaryWriter(File.Open(localPath, FileMode.Create)))
    {
        int byteRead = 0;
        do
        {
            byte[] buffer = reader.ReadBytes(READ_BUFFER_SIZE);
            byteRead = buffer.Length;
            writer.Write(buffer);
            byteTransfered += byteRead;
        } while (byteRead == READ_BUFFER_SIZE);                        
    }                
}
3
Seraphim's