一种优雅的消费方式(a的所有字节)BinaryReader?

Sam*_*r83 63 .net c# stream streamreader binaryreader

是否有优雅的模拟StreamReader.ReadToEnd方法BinaryReader?也许将所有字节放入一个字节数组?

我这样做:

read1.ReadBytes((int)read1.BaseStream.Length);
Run Code Online (Sandbox Code Playgroud)

......但必须有更好的方法.

Sco*_*pey 93

简单地说:

byte[] allData = read1.ReadBytes(int.MaxValue);
Run Code Online (Sandbox Code Playgroud)

文件说,它会读取所有字节,直到到达流的末尾.


更新

虽然这看起来很优雅,并且文档似乎表明这可行,但实际的实现(在.NET 2,3.5和4中检查)为数据分配了一个全大小的字节数组,这可能会导致OutOfMemoryException32比特系统.

因此,我会说实际上没有一种优雅的方式.

相反,我会推荐@ 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();
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 这给了我.NET 4.0中的OutOfMemoryException(使用LINQPad进行测试).实际上,使用Reflector反编译源会显示ReadBytes尝试分配一个大小为给定计数的字节数组:byte [] buffer = new byte [count] ;. (11认同)

ian*_*ano 69

使用BinaryReader 没有一种简单的方法.如果您不知道需要提前阅读的计数,最好的办法是使用MemoryStream:

public byte[] ReadAllBytes(Stream stream)
{
    using (var ms = new MemoryStream())
    {
        stream.CopyTo(ms);
        return ms.ToArray();
    }
}
Run Code Online (Sandbox Code Playgroud)

要在调用时避免使用附加副本ToArray(),您可以改为通过Position和返回缓冲区GetBuffer().

  • 我会添加stream.Position = 0; 在CopyTo之前 (2认同)
  • @GustavoBaiocchiCosta `yourBinaryReader.BaseStream` (2认同)