我当前的方法是将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();
答案 0 :(得分:3)
如果在开始使用之前知道数据的长度,则:您可以分配一个简单的byte[]
并将其填充到读取循环中,只需将每个读取的偏移量增加为读取的字节数即可(并递减“允许触摸的字节数”。确实取决于有一个read
重载/ API,它可以接受偏移量或指针。
如果不是这种选择:GetBuffer()
是您最好的选择-它不会重复数据;而是会为您提供当前可能过大的 byte[]
。由于尺寸过大,因此必须将其与当前的.Length
结合使用,也许将长度/数据对包装在ArraySegment<byte>
或Span<byte>
/ Memory<byte>
中。
在“长度已知”的情况下,如果您愿意使用超大的缓冲区,则还可以考虑通过ArrayPool<byte>.Shared
租用已租出的数组-租用< em>至少该大小,填充它,然后将分段/跨度限制为填充的部分(并记得在完成后将其放回池中)。