我正在创建几个字节数组,需要连接起来创建一个大字节数组 – 我不喜欢使用byte [],但在这里没有选择…
我将其添加到列表中,因为我创建它们,所以一旦我有了所有的字节[],我只需要进行连接,但是我的问题是,实际做什么最好的方法是什么?
当我有一个未知数字的字节[]的列表,我想把它们全部连在一起.
谢谢.
解决方法
listOfByteArrs.SelectMany(byteArr=>byteArr).ToArray()
上面的代码将一系列字节序列连接成一个序列,并将结果存储在一个数组中.
虽然可读,但这不是最有效的 – 它没有使用您已经知道结果字节数组的长度的事实,因此可以避免动态扩展的.ToArray()实现,这必然涉及多个分配和阵列副本.此外,SelectMany是根据迭代器实现的;这意味着很多接口调用相当慢.然而,对于small-ish数据集大小,这不太重要.
如果您需要更快的实施,您可以执行以下操作:
var output = new byte[listOfByteArrs.Sum(arr=>arr.Length)]; int writeIdx=0; foreach(var byteArr in listOfByteArrs) { byteArr.CopyTo(output,writeIdx); writeIdx += byteArr.Length; }
或者如Martinho所说:
var output = new byte[listOfByteArrs.Sum(arr => arr.Length)]; using(var stream = new MemoryStream(output)) foreach (var bytes in listOfByteArrs) stream.Write(bytes,bytes.Length);
一些时间:
var listOfByteArrs = Enumerable.Range(1,1000) .Select(i=>Enumerable.Range(0,i).Select(x=>(byte)x).ToArray()).ToList();
使用short方法连接这些500500字节需要15ms,使用快速方法在我的机器 – YMMV上需要0.5ms,并注意到对于许多应用程序来说都要足够快;-).
最后,您可以使用静态Array.Copy,低级别的BufferBlockCopy或具有预分配的后台缓冲区的MemoryStream替换Array.CopyTo,这些都在我的测试(x64 .NET 4.0)上执行得非常相似.