【问题标题】:Superimpose a stream on top of a byte array在字节数组上叠加一个流
【发布时间】:2021-04-28 20:13:09
【问题描述】:

在 C#/.NET 中是否有任何方法可以在现有的 byte[] 上“叠加”或映射 MemoryStream,以免不必要地复制数据?

在尝试将byte[] 转换为流时,标准解决方案是使用MemoryStream 及其Write 函数,如下所示:

byte[] myArray = new byte[10]; // or, e.g. retrieve from DB
MemoryStream stream = new MemoryStream();
stream.Write(myArray, 0, myArray.Length);

或者,这可以缩短为:

byte[] myArray = new byte[10]; // or, e.g. retrieve from DB
MemoryStream stream = new MemoryStream(myArray);

其实是一回事。

这存在必须将数组的全部内容复制到流中的问题,因此占用了 2X 的内存量。考虑到字节数组可能非常大,这似乎并不令人满意。数据已经在内存中,在一个连续的块中,所以...

内存流能否以某种方式原地映射到字节数组?

【问题讨论】:

    标签: c# .net .net-core binary-data


    【解决方案1】:

    您在第二个块中提到的MemoryStream 构造函数实际上做了您想要的。它保存您提供的数组并将其用作流的后备缓冲区。您可以修改数组,如果这些字节仍未被读取,这些更改将反映在流中。

    这是一个可重现的最小示例来证明这一点。

    byte[] source = new byte[] { 0, 1, 2, 3 };
    MemoryStream stream = new MemoryStream(source);
    
    // If the constructor made a copy, the stream won't be
    // affected and it will output 0 below.
    source[0] = 10;
    
    byte b = (byte)stream.ReadByte();
    
    Console.WriteLine(b);
    

    输出:

    10

    Try it out!

    请注意,当您使用该构造函数时,流无法增长。根据其documentation

    流的长度不能设置为大于指定字节数组初始长度的值;但是,流可以被截断(参见 SetLength)。

    允许它增长会打破它正在使用该缓冲区的期望,因为增长需要分配一个新数组并将数据复制到其中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-15
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      相关资源
      最近更新 更多