问题描述
从输入流创建字节数组的首选方法是什么?
What is the prefered method for creating a byte array from an input stream?
这是我目前使用 .NET 3.5 的解决方案.
Here is my current solution with .NET 3.5.
Stream s;
byte[] b;
using (BinaryReader br = new BinaryReader(s))
{
b = br.ReadBytes((int)s.Length);
}
读取和写入流的块仍然是一个更好的主意吗?
Is it still a better idea to read and write chunks of the stream?
推荐答案
这真的取决于你是否可以信任 s.Length
.对于许多流,您只是不知道会有多少数据.在这种情况下——在 .NET 4 之前——我会使用这样的代码:
It really depends on whether or not you can trust s.Length
. For many streams, you just don't know how much data there will be. In such cases - and before .NET 4 - I'd use code like this:
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()
.任务完成.
With .NET 4 and above, I'd use Stream.CopyTo
, which is basically equivalent to the loop in my code - create the MemoryStream
, call stream.CopyTo(ms)
and then return ms.ToArray()
. Job done.
我或许应该解释一下为什么我的答案比其他人长.Stream.Read
不保证它会读取它所要求的所有内容.例如,如果您正在从网络流中读取数据,它可能会读取一个数据包的价值然后返回,即使很快会有更多数据.BinaryReader.Read
将一直持续到流结束或您指定的大小,但您仍然必须知道开始的大小.
I should perhaps explain why my answer is longer than the others. Stream.Read
doesn't guarantee that it will read everything it's asked for. If you're reading from a network stream, for example, it may read one packet's worth and then return, even if there will be more data soon. BinaryReader.Read
will keep going until the end of the stream or your specified size, but you still have to know the size to start with.
上述方法将继续读取(并复制到 MemoryStream
)直到数据用完.然后它要求 MemoryStream
返回数组中数据的副本.如果您知道开始的大小 - 或 认为 您知道大小,但不确定 - 您可以将 MemoryStream
构造为开始的大小.同样,您可以在最后进行检查,如果流的长度与缓冲区的大小相同(由 MemoryStream.GetBuffer
) 那么你可以只返回缓冲区.所以上面的代码不是很优化,但至少是正确的.它不承担关闭流的任何责任——调用者应该这样做.
The above method will keep reading (and copying into a MemoryStream
) until it runs out of data. It then asks the MemoryStream
to return a copy of the data in an array. If you know the size to start with - or think you know the size, without being sure - you can construct the MemoryStream
to be that size to start with. Likewise you can put a check at the end, and if the length of the stream is the same size as the buffer (returned by MemoryStream.GetBuffer
) then you can just return the buffer. So the above code isn't quite optimised, but will at least be correct. It doesn't assume any responsibility for closing the stream - the caller should do that.
请参阅这篇文章了解更多信息(以及替代实现).
See this article for more info (and an alternative implementation).
这篇关于从流中创建字节数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!