使用StreamReader.ReadToEnd
模仿BinaryReader
方法是否优雅?也许将所有字节都放入一个字节数组中?
我这样做:
read1.ReadBytes((int)read1.BaseStream.Length);
......但必须有更好的方法。
答案 0 :(得分:89)
简单地说:
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();
}
}
答案 1 :(得分:68)
使用BinaryReader没有简单方法。如果您不知道需要提前阅读的计数,最好的办法是使用MemoryStream:
public byte[] ReadAllBytes(Stream stream)
{
using (var ms = new MemoryStream())
{
stream.CopyTo(ms);
return ms.ToArray();
}
}
要在拨打ToArray()
时避免使用其他副本,您可以通过Position
返回GetBuffer()
和缓冲区。
答案 2 :(得分:3)
要将流的内容复制到另一个,我已经解决了阅读"一些"到达文件末尾的字节数:
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 :(得分:0)
我使用它,它利用基础 BaseStream
属性为您提供所需的长度信息。它使事情变得美好而简单。
以下是 BinaryReader
上的三个扩展方法:
Range
类型来指定您感兴趣的数据子集。public static class BinaryReaderExtensions {
public static byte[] ReadBytesToEnd(this BinaryReader binaryReader) {
var length = binaryReader.BaseStream.Length - binaryReader.BaseStream.Position;
return binaryReader.ReadBytes((int)length);
}
public static byte[] ReadAllBytes(this BinaryReader binaryReader) {
binaryReader.BaseStream.Position = 0;
return binaryReader.ReadBytes((int)binaryReader.BaseStream.Length);
}
public static byte[] ReadBytes(this BinaryReader binaryReader, Range range) {
var (offset, length) = range.GetOffsetAndLength((int)binaryReader.BaseStream.Length);
binaryReader.BaseStream.Position = offset;
return binaryReader.ReadBytes(length);
}
}
使用它们是微不足道的和清晰的......
// 1 - Reads everything in as a byte array
var rawBytes = myBinaryReader.ReadAllBytes();
// 2 - Reads a string, then reads the remaining data as a byte array
var someString = myBinaryReader.ReadString();
var rawBytes = myBinaryReader.ReadBytesToEnd();
// 3 - Uses a range to read the last 44 bytes
var rawBytes = myBinaryReader.ReadBytes(^44..);
答案 4 :(得分:0)
遇到了同样的问题。
首先,使用 FileInfo.Length.
获取文件的大小
接下来,创建一个字节数组并将其值设置为 BinaryReader.ReadBytes(FileInfo.Length)。
例如
var size = new FileInfo(yourImagePath).Length;
byte[] allBytes = yourReader.ReadBytes(System.Convert.ToInt32(size));
答案 5 :(得分:-1)
解决此问题的另一种方法是使用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();
}
}
}
使用这种方法将允许可重用和可读的代码。