从流中创建字节数组

Creating a byte array from a stream(从流中创建字节数组)
本文介绍了从流中创建字节数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从输入流创建字节数组的首选方法是什么?

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).

这篇关于从流中创建字节数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)