从 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 它到游泳池时完成)。
我目前的做法是将 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 它到游泳池时完成)。