c# - 从流创建字节数组

标签 c# .net-3.5 inputstream

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

这是我当前使用 .NET 3.5 的解决方案。

Stream s;
byte[] b;

using (BinaryReader br = new BinaryReader(s))
{
    b = br.ReadBytes((int)s.Length);
}

读取和写入流的 block 仍然是更好的主意吗?

最佳答案

这实际上取决于您是否可以信任 s.Length。对于许多流,您只是不知道会有多少数据。在这种情况下——在 .NET 4 之前——我会使用这样的代码:

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()。工作完成。

我或许应该解释一下为什么我的回答比其他人长。 Stream.Read不保证它会阅读它所要求的一切。例如,如果您正在从网络流中读取数据,它可能会读取一个数据包的值(value)然后返回,即使很快会有更多数据。 BinaryReader.Read将一直持续到流结束或您指定的大小,但您仍然需要知道开始的大小。

上述方法将继续读取(并复制到 MemoryStream)直到用完数据。然后它要求 MemoryStream 返回一个数组中的数据副本。如果您知道开始的大小 - 或者认为您知道大小,但不确定 - 您可以将 MemoryStream 构造为开始的大小。同样,您可以在末尾进行检查,如果流的长度与缓冲区的大小相同(由 MemoryStream.GetBuffer 返回),那么您可以只返回缓冲区。所以上面的代码不是很优化,但至少是正确的。它不承担关闭流的任何责任 - 调用者应该这样做。

参见 this article了解更多信息(以及替代实现)。

关于c# - 从流创建字节数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/221925/

相关文章:

c# - 如何修改 CompositeControl 的 ClientId,消除所述 ID 的呈现,而不影响 ChildControls?

linq - 在 .NET 3.5 中的枚举列表上使用 List.Find 或 LINQ

.net - .NET 3.5 是否有广泛使用的模式和接口(interface)库?

java - inputStream 字符串不同于字符串字面量

c# - 有没有办法禁止smtp透明转发?

c# - 使用 Linq 比较两个列表以进行部分匹配

java - (树莓派csi相机)用java从raspivid-stdout读取h264数据

java - 到达EOS后重置Java Socket的InputStream

C# 访问修饰符取决于状态

C#、WPF、在没有 backgroundworkers 的情况下更新 gui