有没有一种优雅的StreamReader.ReadToEnd
方法可以模仿BinaryReader
?也许将所有字节放入字节数组中?
我这样做:
read1.ReadBytes((int)read1.BaseStream.Length);
...但是必须有更好的方法。
Answers:
只需做:
byte[] allData = read1.ReadBytes(int.MaxValue);
该文档说它将读取所有字节,直到到达流的末尾。
尽管这看起来很优雅,并且文档似乎表明这可以工作,但实际的实现(在.NET 2、3.5和4中进行了检查)为数据分配了一个全尺寸的字节数组,这可能会导致OutOfMemoryException
32位系统。
因此,我要说实际上并没有一种优雅的方法。
相反,我建议使用@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();
}
}
int.MaxValue
32位整数的数组,则将分配8GB的内存...因此,这就是为什么您应该使用较小的缓冲区构建结果的原因!
使用BinaryReader没有简单的方法。如果您不知道需要提前读取的计数,那么更好的选择是使用MemoryStream:
public byte[] ReadAllBytes(Stream stream)
{
using (var ms = new MemoryStream())
{
stream.CopyTo(ms);
return ms.ToArray();
}
}
为了避免在调用时产生额外的副本ToArray()
,您可以改为通过Position
和返回and缓冲区GetBuffer()
。
Stream.CopyTo
只提供.NET 4
Stream
但该类的Length
属性始终为零。最初,我尝试了基于扩展方法的方法,但是感觉很麻烦。
yourBinaryReader.BaseStream
要将流的内容复制到另一个,我解决了读取“一些”字节直到到达文件末尾的问题:
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);
}
}
解决此问题的另一种方法是使用C#扩展方法:
public static class StreamHelpers
{
public static byte[] ReadAllBytes(this BinaryReader reader)
{
// Pre .Net version 4.0
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();
}
// .Net 4.0 or Newer
using (var ms = new MemoryStream())
{
stream.CopyTo(ms);
return ms.ToArray();
}
}
}
使用这种方法将允许可重用和可读的代码。