问题描述
如何从字节数组中删除多个字节?
How would I go about removing a number of bytes from a byte array?
推荐答案
正如nobugz的评论(和Reed Copsey的回答)所提到的,如果您实际上不需要将结果作为字节数组,则应考虑使用 ArraySegment<T>
:
As nobugz's comment (and Reed Copsey's answer) mentions, if you don't actually need the result as a byte array, you should look into using ArraySegment<T>
:
ArraySegment<byte> segment = new ArraySegment<byte>(full, 16, full.Length - 16);
否则,将需要复制-数组始终具有固定大小,因此您不能从现有数组中删除"前16个字节.取而代之的是,您必须创建一个较小的新数组,并将相关数据复制到其中.
Otherwise, copying will be necessary - arrays always have a fixed size, so you can't "remove" the first 16 bytes from the existing array. Instead, you'll have to create a new, smaller array and copy the relevant data into it.
对于非LINQ方法,Zach的建议是正确的,但是可以使它更简单(假设您已经知道原始数组的长度至少为16个字节):
Zach's suggestion is along the right lines for the non-LINQ approach, but it can be made simpler (this assumes you already know the original array is at least 16 bytes long):
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
会稍快一些,但我不确定.
I suspect Buffer.BlockCopy
will be slightly faster, but I don't know for sure.
请注意,如果涉及的数组很大,则这两种方法都可能比LINQ方法效率更高:LINQ方法要求每个字节都从迭代器中分别返回,并可能要进行中间复制(以相同的方式)因为将项目添加到List<T>
需要定期增长后备阵列).显然,不要进行微优化,但是如果这部分代码是性能瓶颈,则值得检查.
Note that both of these could be significantly more efficient than the LINQ approach if the arrays involved are big: the LINQ approach requires each byte to be individually returned from an iterator, and potentially intermediate copies to be made (in the same way as adding items to a List<T>
needs to grow the backing array periodically). Obviously don't micro-optimise, but it's worth checking if this bit of code is a performance bottleneck.
我对这三种方法进行了非常快速而肮脏的"基准测试.我不相信基准可以区分Buffer.BlockCopy
和Array.Copy
-它们非常接近-但是LINQ方法慢了100倍以上.
I ran a very "quick and dirty" benchmark of the three approaches. I don't trust the benchmark to distinguish between Buffer.BlockCopy
and Array.Copy
- they were pretty close - but the LINQ approach was over 100 times slower.
在我的笔记本电脑上,使用10,000个元素的字节数组,用LINQ花了近10秒钟执行了40,000个拷贝;上述方法完成相同数量的工作大约需要80毫秒.我将迭代次数增加到4,000,000,但仍然只花了大约7秒钟.显然,适用于微基准测试的一般警告,但这是一个相当大的差异.
On my laptop, using byte arrays of 10,000 elements, it took nearly 10 seconds to perform 40,000 copies using LINQ; the above approaches took about 80ms to do the same amount of work. I upped the iteration count to 4,000,000 and it still only took about 7 seconds. Obviously the normal caveats around micro-benchmarks apply, but this is a pretty significat difference.
如果这在对性能很重要的代码路径中,请绝对使用上述方法:
Definitely use the above approach if this is in a code path which is important to performance :)
这篇关于删除前16个字节?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!