如何有效地获取C#中字节数组(前N个元素)的子集?
我有一个最大大小为1K的字节数组缓冲区。我想写出数组的一个子集(子集的开头总是元素0,但我们感兴趣的长度是一个变量) 这里的应用是压缩。我将缓冲区传递给压缩函数。为简单起见,假设压缩将产生相等或小于1K字节的数据如何有效地获取C#中字节数组(前N个元素)的子集?,c#,.net,C#,.net,我有一个最大大小为1K的字节数组缓冲区。我想写出数组的一个子集(子集的开头总是元素0,但我们感兴趣的长度是一个变量) 这里的应用是压缩。我将缓冲区传递给压缩函数。为简单起见,假设压缩将产生相等或小于1K字节的数据 byte[] buffer = new byte[1024]; while (true) { uncompressedData = GetNextUncompressedBlock(); int compressedLength = compress(buffer, u
byte[] buffer = new byte[1024];
while (true)
{
uncompressedData = GetNextUncompressedBlock();
int compressedLength = compress(buffer, uncompressedData);
// Here, compressedBuffer[0..compressedLength - 1] is what we're interested in
// There's a method now with signature Write(byte[] compressedData) that
// I won't be able to change. Short of allocating a custom sized buffer,
// and copying data into the custom sized buffer... is there any other
// technique I could use to only expose the data I want?
}
我真的希望避免在这里复制—它似乎完全没有必要,因为所需的所有数据都已经在
缓冲区中了。如果您不能更改方法签名,那么您就卡住了。无法在byte[]类型的字节数组上创建“视图”。理想的解决方案是,该操作要么采用ArraySegment
要么采用byte[]
后跟偏移量和计数。如果您真的无法更改写入方法,那么不幸的是,您只能创建一个新数组并将数据复制到其中。如果方法签名是(byte[])
,则只能进行复制
如果您可以更改签名:
- 流支持写入数组的子集,因此请求具有以下签名并不罕见:
公共摘要无效写入(
字节[]缓冲区,
整数偏移,
整数计数)
- 另一个选项是传递
IEnumerable
,这样就可以按任何方式切片数组,而无需复制
Buffer.BlockCopy将是我的选择
Microsoft示例:
您的代码如下所示:
uncompressedData = GetNextUncompressedBlock();
int compressedLength = compress(buffer, uncompressedData);
Buffer.BlockCopy(buffer, 0, buffer, 0, compressedLength);
你不可能做到。与其更改数组的长度,不如将其复制到新的数组实例
但是,您可以使用性能更好的:
Buffer提供了将字节从一个基元类型数组复制到另一个基元类型数组、从数组中获取字节、在数组中设置字节以及获取数组长度的方法。与System.Array类中的类似方法相比,此类在操作基元类型方面提供了更好的性能
这符合您的需要,因为您有一个字节数组,字节是基本类型。byte[]b=newbyte[]{1,2,3,4,5};
byte[] b = new Byte[] {1, 2, 3, 4, 5};
IEnumerable<Byte> middle = b.Skip(2).Take(3);
IEnumerable middle=b.Skip(2)、Take(3);
这会让你得到任何你喜欢的中间部分。这很可能是一个副本,但我认为您不应该试图避免这种情况。哇,您以前曾帮助我使用WCF(作为一个不同的用户)。再次感谢Carlos+1的提示。
byte[] b = new Byte[] {1, 2, 3, 4, 5};
IEnumerable<Byte> middle = b.Skip(2).Take(3);