删除前16个字节?

我如何从字节数组中删除多个字节?

编辑:正如nobugz的评论(和Reed Copsey的回答)提到的,如果你实际上不需要将结果作为字节数组,你应该研究使用ArraySegment

 ArraySegment segment = new ArraySegment(full, 16, full.Length - 16); 

否则,必须进行复制 – 数组总是具有固定大小,因此您无法从现有数组中“删除”前16个字节。 相反,您必须创建一个新的较小的数组并将相关数据复制到其中。

Zach的建议是非LINQ方法的正确行,但它可以更简单(假设您已经知道原始数组至少16个字节长):

 byte[] newArray = new byte[oldArray.Length - 16]; Buffer.BlockCopy(oldArray, 16, newArray, 0, newArray.Length); 

要么

 byte[] newArray = new byte[oldArray.Length - 16]; Array.Copy(oldArray, 16, newArray, 0, newArray.Length); 

怀疑 Buffer.BlockCopy会稍快,但我不确定。

请注意,如果涉及的数组很大,这两者都可能比LINQ方法更有效:LINQ方法要求从迭代器单独返回每个字节,并且可能要生成中间副本(与添加项目的方式相同)到List需要定期增长后备arrays。 显然不要进行微优化,但值得检查这段代码是否是性能瓶颈。

编辑:我对这三种方法进行了非常“快速而肮脏”的基准测试。 我不相信基准来区分Buffer.BlockCopyArray.Copy – 它们非常接近 – 但LINQ方法慢了100多倍。

在我的笔记本电脑上,使用10,000个元素的字节数组,使用LINQ执行40,000个拷贝花了将近10秒; 上述方法花了大约80ms来完成相同的工作量。 我将迭代次数增加到4,000,000,它仍然只用了大约7秒。 显然,微基准测试的正常警告适用,但这是一个非常显着的差异。

如果这是在一个对性能很重要的代码路径中,绝对使用上面的方法:)

你可以这样做:

 using System.Linq // ... var newArray = oldArray.Skip(numBytes).ToArray(); 

我还要提到 – 根据您计划如何使用结果,通常,另一种方法是使用ArraySegment来访问数组的剩余部分。 这可以防止复制arrays的需要,这在某些使用场景中可能更有效:

 ArraySegment segment = new ArraySegment(originalArray, 16, originalArray.Length-16); // Use segment how you'd use your array... 

如果你不能使用Linq,你可以这样做:

 byte[] myArray = // however you acquire the array byte[] newArray = new byte[myArray.Length - 16]; for (int i = 0; i < newArray.Length; i++) { newArray[i] = myArray[i + 16]; } // newArray is now myArray minus the first 16 bytes 

您还需要处理数组长度小于16个字节的情况。