简体   繁体   English

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

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

My current approach is to read the COM stream into a C# MemoryStream and then call .toArray. 我当前的方法是将COM流读取到C#MemoryStream中,然后调用.toArray。 However, I believe toArray creates a redundant copy of the data. 但是,我相信toArray会创建数据的冗余副本。 Is there a better way that has reduced memory usage as the priority? 有没有更好的方法来减少内存使用量?

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();

If you know the length of the data before you start consuming it, then: you can allocate a simple byte[] and fill that in your read loop simply by incrementing an offset each read with the number of bytes read (and decrementing your "number of bytes you're allowed to touch). This does depend on having a read overload / API that accepts either an offset or a pointer, though. 如果在开始使用之前知道数据的长度,则:您可以分配一个简单的byte[]并将其填充到您的读取循环中,只需将每次读取的偏移量增加为读取的字节数即可(并减少“数字”允许您触摸的字节数),但这确实取决于read过载/ API是否接受偏移量或指针。

If that isn't an option: GetBuffer() is your best bet - it doesn't duplicate the data; 如果那不是一个选择: GetBuffer()是最好的选择-它不会重复数据; rather it hands you the current possibly oversized byte[] . 而是将当前可能过大的 byte[]交给您。 Because it is oversized, you must consider it in combination with the current .Length , perhaps wrapping the length/data pair in either a ArraySegment<byte> , or a Span<byte> / Memory<byte> . 因为它过大,所以必须将其与当前.Length结合使用,也许将长度/数据对包装在ArraySegment<byte>Span<byte> / Memory<byte>

In the "the length is known" scenario, if you're happy to work with oversized buffers, you could also consider a leased array, via ArrayPool<byte>.Shared - rent one of at least that size, fill it, then constrain your segment/span to the populated part (and remember to return it to the pool when you're done). 在“长度已知”的情况下,如果您乐于使用超大的缓冲区,则还可以通过ArrayPool<byte>.Shared考虑租用的数组。 ArrayPool<byte>.Shared -租用至少一个该大小的数组,填充它,然后约束您的细分/跨度到填充的部分(完成后,请记住将其返回到池中)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM