将流叠加在字节数组之上

Superimpose a stream on top of a byte array

在 C#/.NET 中是否有任何方法可以将 MemoryStream“叠加”或映射到现有 byte[] 之上,这样数据就不会被不必要地使用复制了吗?

在尝试将 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);

其实是一回事

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

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

你在第二个块中提到的 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:

The length of the stream cannot be set to a value greater than the initial length of the specified byte array; however, the stream can be truncated (see SetLength).

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