连接byte []的C#列表

Ada*_*obb 11 c# bytearray list concatenation

我正在创建几个需要连接在一起创建一个大字节数组的字节数组 - 我宁愿不使用byte [],但在这里别无选择......

我在创建它时将每个添加到List中,所以我只需要在拥有所有byte []后进行连接,但我的问题是,实际执行此操作的最佳方法是什么?

当我有一个包含未知数量的byte []的列表时,我想将它们连在一起.

谢谢.

Eam*_*nne 20

listOfByteArrs.SelectMany(byteArr=>byteArr).ToArray()
Run Code Online (Sandbox Code Playgroud)

上面的代码将一系列字节序列连接成一个序列 - 并将结果存储在一个数组中.

虽然可读,但这并不是最有效的 - 它没有利用您已经知道结果字节数组长度的事实,因此可以避免动态扩展.ToArray()实现,这必然涉及多个分配和数组副本.此外,SelectMany是根据迭代器实现的; 这意味着很多+很多接口调用很慢.但是,对于小型数据集大小,这不太重要.

如果您需要更快的实施,您可以执行以下操作:

var output = new byte[listOfByteArrs.Sum(arr=>arr.Length)];
int writeIdx=0;
foreach(var byteArr in listOfByteArrs) {
    byteArr.CopyTo(output, writeIdx);
    writeIdx += byteArr.Length;
}
Run Code Online (Sandbox Code Playgroud)

或者Martinho建议:

var output = new byte[listOfByteArrs.Sum(arr => arr.Length)];
using(var stream = new MemoryStream(output))
    foreach (var bytes in listOfByteArrs)
        stream.Write(bytes, 0, bytes.Length);
Run Code Online (Sandbox Code Playgroud)

一些时间:

var listOfByteArrs = Enumerable.Range(1,1000)
    .Select(i=>Enumerable.Range(0,i).Select(x=>(byte)x).ToArray()).ToList();
Run Code Online (Sandbox Code Playgroud)

使用短方法连接这些500500字节需要15ms,使用快速方法在我的机器上需要0.5ms - YMMV,并注意对于许多应用程序来说两者都足够快;-).

最后,你可以取代Array.CopyTostatic Array.Copy中,低层次的Buffer.BlockCopy,或者MemoryStream具有预分配后缓冲区-这些都在我的测试中(64位.NET 4.0)执行几乎相同.

  • 虽然简短明了,但请注意,与传统解决方案相比,此代码非常慢.如果它足够快,很棒,但它可能不够快. (4认同)