从 COM 流读取到 c# byte[] 的内存有效方式

memory efficient way to read from COM stream to c# byte[]

我目前的做法是将 COM 流读入 C# MemoryStream,然后调用 .toArray。但是,我相信 toArray 会创建数据的冗余副本。有没有更好的方法以减少内存使用为优先?

var memStream = new MemoryStream(10000);
var chunk = new byte[1000];
while (true)
{
 int bytesRead = comStream.read(ref chunk, chunk.Length);
 if (bytesRead == 0)
   break; // eos
 memStream.Write(chunk, 0, bytesRead);
}

//fairly sure this creates a duplicate copy of the data
var array = memStream.ToArray();

//does this also dupe the data?
var array2 = memStream.GetBuffer();

如果您在开始使用数据之前就知道数据的长度,那么:您可以分配一个简单的 byte[] 并将其填充到读取循环中,只需每次读取的字节数增加一个偏移量即可阅读(并减少您的“允许触摸的字节数”)。这 确实 取决于 read 重载/ API 接受偏移量还是一个指针。

如果那不是一个选项:GetBuffer() 是您最好的选择 - 它不会复制数据;相反,它会为您提供当前 可能超大 byte[]。因为它太大了,你必须结合当前的 .Length 来考虑它,也许将 length/data 对包装在 ArraySegment<byte>Span<byte>/[=17= 中].

在 "the length is known" 场景中,如果您乐于使用超大缓冲区,您还可以考虑 leased 数组,通过 ArrayPool<byte>.Shared -租 至少 那个大小的其中之一,填充它,然后将你的 segment/span 限制在人口稠密的部分(并记得 return 它到游泳池时完成)。