在c#中组合两个或多个字节数组的最佳方法

时间:2022-06-24 12:18:55

I have 3 byte arrays in C# that I need to combine into one. What would be the most efficient method to complete this task?

c#中有3个字节数组,需要合并成一个字节数组。完成这项任务最有效的方法是什么?

12 个解决方案

#1


268  

For primitive types (including bytes), use System.Buffer.BlockCopy instead of System.Array.Copy. It's faster.

对于原始类型(包括字节),使用System.Buffer。BlockCopy代替System.Array.Copy。这是更快。

I timed each of the suggested methods in a loop executed 1 million times using 3 arrays of 10 bytes each. Here are the results:

我在一个循环中对每个建议的方法进行了计时,循环执行了100万次,每个循环使用3个10字节的数组。这里是结果:

  1. New Byte Array using System.Array.Copy - 0.2187556 seconds
  2. 新的字节数组使用System.Array。复制- 0.2187556秒
  3. New Byte Array using System.Buffer.BlockCopy - 0.1406286 seconds
  4. 使用System.Buffer的新字节数组。BlockCopy - 0.1406286秒
  5. IEnumerable<byte> using C# yield operator - 0.0781270 seconds
  6. IEnumerable ,使用c#屈服算子- 0.0781270秒
  7. IEnumerable<byte> using LINQ's Concat<> - 0.0781270 seconds
  8. 使用LINQ的Concat<> - 0.0781270秒的IEnumerable

I increased the size of each array to 100 elements and re-ran the test:

我将每个数组的大小增加到100个元素,并重新运行测试:

  1. New Byte Array using System.Array.Copy - 0.2812554 seconds
  2. 新的字节数组使用System.Array。复制- 0.2812554秒
  3. New Byte Array using System.Buffer.BlockCopy - 0.2500048 seconds
  4. 使用System.Buffer的新字节数组。BlockCopy - 0.2500048秒
  5. IEnumerable<byte> using C# yield operator - 0.0625012 seconds
  6. IEnumerable ,使用c#屈服算子- 0.0625012秒
  7. IEnumerable<byte> using LINQ's Concat<> - 0.0781265 seconds
  8. 使用LINQ的Concat<> - 0.0781265秒的IEnumerable

I increased the size of each array to 1000 elements and re-ran the test:

我将每个数组的大小增加到1000个元素并重新运行测试:

  1. New Byte Array using System.Array.Copy - 1.0781457 seconds
  2. 新的字节数组使用System.Array。复制- 1.0781457秒
  3. New Byte Array using System.Buffer.BlockCopy - 1.0156445 seconds
  4. 使用System.Buffer的新字节数组。BlockCopy - 1.0156445秒
  5. IEnumerable<byte> using C# yield operator - 0.0625012 seconds
  6. IEnumerable ,使用c#屈服算子- 0.0625012秒
  7. IEnumerable<byte> using LINQ's Concat<> - 0.0781265 seconds
  8. 使用LINQ的Concat<> - 0.0781265秒的IEnumerable

Finally, I increased the size of each array to 1 million elements and re-ran the test, executing each loop only 4000 times:

最后,我将每个数组的大小增加到100万个元素,并重新运行测试,每个循环只执行4000次:

  1. New Byte Array using System.Array.Copy - 13.4533833 seconds
  2. 新的字节数组使用System.Array。复制- 13.4533833秒
  3. New Byte Array using System.Buffer.BlockCopy - 13.1096267 seconds
  4. 使用System.Buffer的新字节数组。BlockCopy - 13.1096267秒
  5. IEnumerable<byte> using C# yield operator - 0 seconds
  6. IEnumerable ,使用c#屈服算子- 0秒
  7. IEnumerable<byte> using LINQ's Concat<> - 0 seconds
  8. IEnumerable ,使用LINQ的Concat<> - 0秒

So, if you need a new byte array, use

因此,如果需要一个新的字节数组,请使用

byte[] rv = new byte[a1.Length + a2.Length + a3.Length];
System.Buffer.BlockCopy(a1, 0, rv, 0, a1.Length);
System.Buffer.BlockCopy(a2, 0, rv, a1.Length, a2.Length);
System.Buffer.BlockCopy(a3, 0, rv, a1.Length + a2.Length, a3.Length);

But, if you can use an IEnumerable<byte>, DEFINITELY prefer LINQ's Concat<> method. It's only slightly slower than the C# yield operator, but is more concise and more elegant.

但是,如果您可以使用IEnumerable ,那么一定要使用LINQ的Concat<>方法。它只比c# yield运算符慢一点,但更简洁、更优雅。

IEnumerable<byte> rv = a1.Concat(a2).Concat(a3);

If you have an arbitrary number of arrays and are using .NET 3.5, you can make the System.Buffer.BlockCopy solution more generic like this:

如果你有任意数量的数组并且正在使用。net 3.5,你可以创建System.Buffer。块拷贝解决方案更通用如下:

private byte[] Combine(params byte[][] arrays)
{
    byte[] rv = new byte[arrays.Sum(a => a.Length)];
    int offset = 0;
    foreach (byte[] array in arrays) {
        System.Buffer.BlockCopy(array, 0, rv, offset, array.Length);
        offset += array.Length;
    }
    return rv;
}

*Note: The above block requires you adding the following namespace at the the top for it to work.

*注意:上面的块要求您在顶部添加以下名称空间以使其工作。

using System.Linq;

To Jon Skeet's point regarding iteration of the subsequent data structures (byte array vs. IEnumerable<byte>), I re-ran the last timing test (1 million elements, 4000 iterations), adding a loop that iterates over the full array with each pass:

对于Jon Skeet关于后续数据结构(字节数组对IEnumerable )的迭代的观点,我重新运行了最后一次计时测试(100万元素,4000次迭代),并添加一个循环,遍历整个数组,每个遍历:

  1. New Byte Array using System.Array.Copy - 78.20550510 seconds
  2. 新的字节数组使用System.Array。复制- 78.20550510秒
  3. New Byte Array using System.Buffer.BlockCopy - 77.89261900 seconds
  4. 使用System.Buffer的新字节数组。BlockCopy - 77.89261900秒
  5. IEnumerable<byte> using C# yield operator - 551.7150161 seconds
  6. IEnumerable ,使用c# yield operator——551.7150161秒
  7. IEnumerable<byte> using LINQ's Concat<> - 448.1804799 seconds
  8. IEnumerable 使用LINQ的Concat<> - 448.1804799秒。

The point is, it is VERY important to understand the efficiency of both the creation and the usage of the resulting data structure. Simply focusing on the efficiency of the creation may overlook the inefficiency associated with the usage. Kudos, Jon.

关键是,理解创建和使用结果数据结构的效率非常重要。仅仅关注创建的效率可能会忽略与使用相关的低效率。荣誉,乔恩。

#2


122  

Many of the answers seem to me to be ignoring the stated requirements:

在我看来,许多答案似乎忽视了规定的要求:

  • The result should be a byte array
  • 结果应该是一个字节数组
  • It should be as efficient as possible
  • 它应该尽可能地有效

These two together rule out a LINQ sequence of bytes - anything with yield is going to make it impossible to get the final size without iterating through the whole sequence.

这两者一起排除了LINQ字节序列——任何带有yield的元素都不可能在不遍历整个序列的情况下获得最终大小。

If those aren't the real requirements of course, LINQ could be a perfectly good solution (or the IList<T> implementation). However, I'll assume that Superdumbell knows what he wants.

当然,如果这些不是真正的需求,LINQ可能是一个完美的解决方案(或者IList 实现)。然而,我假设超级哑铃知道他想要什么。

(EDIT: I've just had another thought. There's a big semantic difference between making a copy of the arrays and reading them lazily. Consider what happens if you change the data in one of the "source" arrays after calling the Combine (or whatever) method but before using the result - with lazy evaluation, that change will be visible. With an immediate copy, it won't. Different situations will call for different behaviour - just something to be aware of.)

(编辑:我有另外一个想法。复制数组和延迟读取数组之间存在很大的语义差异。考虑一下,如果您在调用Combine(或其他)方法之后,在其中一个“源”数组中更改了数据,但是在使用结果之前(使用惰性计算),那么更改将是可见的。有了即时拷贝,它就不会了。不同的情况需要不同的行为——只是需要注意一些事情。

Here are my proposed methods - which are very similar to those contained in some of the other answers, certainly :)

以下是我提出的方法,它们与其他一些答案中包含的方法非常相似。

public static byte[] Combine(byte[] first, byte[] second)
{
    byte[] ret = new byte[first.Length + second.Length];
    Buffer.BlockCopy(first, 0, ret, 0, first.Length);
    Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
    return ret;
}

public static byte[] Combine(byte[] first, byte[] second, byte[] third)
{
    byte[] ret = new byte[first.Length + second.Length + third.Length];
    Buffer.BlockCopy(first, 0, ret, 0, first.Length);
    Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
    Buffer.BlockCopy(third, 0, ret, first.Length + second.Length,
                     third.Length);
    return ret;
}

public static byte[] Combine(params byte[][] arrays)
{
    byte[] ret = new byte[arrays.Sum(x => x.Length)];
    int offset = 0;
    foreach (byte[] data in arrays)
    {
        Buffer.BlockCopy(data, 0, ret, offset, data.Length);
        offset += data.Length;
    }
    return ret;
}

Of course the "params" version requires creating an array of the byte arrays first, which introduces extra inefficiency.

当然,“params”版本需要首先创建字节数组数组的数组,这会带来额外的效率低下。

#3


26  

If you simply need a new byte array, then use the following:

如果您只是需要一个新的字节数组,那么使用以下命令:

byte[] Combine(byte[] a1, byte[] a2, byte[] a3)
{
    byte[] ret = new byte[a1.Length + a2.Length + a3.Length];
    Array.Copy(a1, 0, ret, 0, a1.Length);
    Array.Copy(a2, 0, ret, a1.Length, a2.Length);
    Array.Copy(a3, 0, ret, a1.Length + a2.Length, a3.Length);
    return ret;
}

Alternatively, if you just need a single IEnumerable, consider using the C# 2.0 yield operator:

或者,如果您只需要一个IEnumerable,可以考虑使用c# 2.0 yield算子:

IEnumerable<byte> Combine(byte[] a1, byte[] a2, byte[] a3)
{
    foreach (byte b in a1)
        yield return b;
    foreach (byte b in a2)
        yield return b;
    foreach (byte b in a3)
        yield return b;
}

#4


26  

I took Matt's LINQ example one step further for code cleanliness:

为了使代码更整洁,我进一步使用了Matt的LINQ示例:

byte[] rv = a1.Concat(a2).Concat(a3).ToArray();

In my case, the arrays are small, so I'm not concerned about performance.

在我的例子中,数组很小,所以我不关心性能。

#5


8  

I actually ran into some issues with using Concat... (with arrays in the 10-million, it actually crashed).

实际上我在使用Concat时遇到了一些问题。(数组在1000万,它实际上崩溃了)。

I found the following to be simple, easy and works well enough without crashing on me, and it works for ANY number of arrays (not just three) (It uses LINQ):

我发现下面的内容简单、容易,并且在不影响我的情况下工作得很好,并且它适用于任意数量的数组(而不仅仅是三个)(它使用LINQ):

public static byte[] ConcatByteArrays(params byte[][]  arrays)
{
    return arrays.SelectMany(x => x).ToArray();
}

#6


5  

The memorystream class does this job pretty nicely for me. I couldn't get the buffer class to run as fast as memorystream.

memorystream类对我来说做得很好。我无法让缓冲区类像memorystream一样快地运行。

using (MemoryStream ms = new MemoryStream())
{
  ms.Write(BitConverter.GetBytes(22),0,4);
  ms.Write(BitConverter.GetBytes(44),0,4);
  ms.ToArray();
}

#7


2  

    public static bool MyConcat<T>(ref T[] base_arr, ref T[] add_arr)
    {
        try
        {
            int base_size = base_arr.Length;
            int size_T = System.Runtime.InteropServices.Marshal.SizeOf(base_arr[0]);
            Array.Resize(ref base_arr, base_size + add_arr.Length);
            Buffer.BlockCopy(add_arr, 0, base_arr, base_size * size_T, add_arr.Length * size_T);
        }
        catch (IndexOutOfRangeException ioor)
        {
            MessageBox.Show(ioor.Message);
            return false;
        }
        return true;
    }

#8


2  

    public static byte[] Concat(params byte[][] arrays) {
        using (var mem = new MemoryStream(arrays.Sum(a => a.Length))) {
            foreach (var array in arrays) {
                mem.Write(array, 0, array.Length);
            }
            return mem.ToArray();
        }
    }

#9


1  

Here's a generalization of the answer provided by @Jon Skeet. It is basically the same, only it is usable for any type of array, not only bytes:

下面是对@Jon Skeet提供的答案的概括。它基本上是一样的,只是适用于任何类型的数组,而不仅仅是字节:

public static T[] Combine<T>(T[] first, T[] second)
{
    T[] ret = new T[first.Length + second.Length];
    Buffer.BlockCopy(first, 0, ret, 0, first.Length);
    Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
    return ret;
}

public static T[] Combine<T>(T[] first, T[] second, T[] third)
{
    T[] ret = new T[first.Length + second.Length + third.Length];
    Buffer.BlockCopy(first, 0, ret, 0, first.Length);
    Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
    Buffer.BlockCopy(third, 0, ret, first.Length + second.Length,
                     third.Length);
    return ret;
}

public static T[] Combine<T>(params T[][] arrays)
{
    T[] ret = new T[arrays.Sum(x => x.Length)];
    int offset = 0;
    foreach (T[] data in arrays)
    {
        Buffer.BlockCopy(data, 0, ret, offset, data.Length);
        offset += data.Length;
    }
    return ret;
}

#10


0  

Can use generics to combine arrays. Following code can easily be expanded to three arrays. This way you never need to duplicate code for different type of arrays. Some of the above answers seem overly complex to me.

可以使用泛型组合数组。下面的代码可以很容易地扩展为三个数组。这样,您就不需要为不同类型的数组重复代码。在我看来,上面的一些答案似乎过于复杂。

private static T[] CombineTwoArrays<T>(T[] a1, T[] a2)
    {
        T[] arrayCombined = new T[a1.Length + a2.Length];
        Array.Copy(a1, 0, arrayCombined, 0, a1.Length);
        Array.Copy(a2, 0, arrayCombined, a1.Length, a2.Length);
        return arrayCombined;
    }

#11


-1  

All you need to pass list of Byte Arrays and this function will return you the Array of Bytes (Merged). This is the best solution i think :).

您只需传递字节数组的列表,此函数将返回字节数组(合并)。我认为这是最好的解决办法。

public static byte[] CombineMultipleByteArrays(List<byte[]> lstByteArray)
        {
            using (var ms = new MemoryStream())
            {
                using (var doc = new iTextSharp.text.Document())
                {
                    using (var copy = new PdfSmartCopy(doc, ms))
                    {
                        doc.Open();
                        foreach (var p in lstByteArray)
                        {
                            using (var reader = new PdfReader(p))
                            {
                                copy.AddDocument(reader);
                            }
                        }

                        doc.Close();
                    }
                }
                return ms.ToArray();
            }
        }

#12


-5  

Concat is the right answer, but for some reason a handrolled thing is getting the most votes. If you like that answer, perhaps you'd like this more general solution even more:

Concat是正确的答案,但是出于某种原因,手卷的东西获得的选票最多。如果你喜欢这个答案,也许你会更喜欢这个更普遍的答案:

    IEnumerable<byte> Combine(params byte[][] arrays)
    {
        foreach (byte[] a in arrays)
            foreach (byte b in a)
                yield return b;
    }

which would let you do things like:

这样你就能做到:

    byte[] c = Combine(new byte[] { 0, 1, 2 }, new byte[] { 3, 4, 5 }).ToArray();

#1


268  

For primitive types (including bytes), use System.Buffer.BlockCopy instead of System.Array.Copy. It's faster.

对于原始类型(包括字节),使用System.Buffer。BlockCopy代替System.Array.Copy。这是更快。

I timed each of the suggested methods in a loop executed 1 million times using 3 arrays of 10 bytes each. Here are the results:

我在一个循环中对每个建议的方法进行了计时,循环执行了100万次,每个循环使用3个10字节的数组。这里是结果:

  1. New Byte Array using System.Array.Copy - 0.2187556 seconds
  2. 新的字节数组使用System.Array。复制- 0.2187556秒
  3. New Byte Array using System.Buffer.BlockCopy - 0.1406286 seconds
  4. 使用System.Buffer的新字节数组。BlockCopy - 0.1406286秒
  5. IEnumerable<byte> using C# yield operator - 0.0781270 seconds
  6. IEnumerable ,使用c#屈服算子- 0.0781270秒
  7. IEnumerable<byte> using LINQ's Concat<> - 0.0781270 seconds
  8. 使用LINQ的Concat<> - 0.0781270秒的IEnumerable

I increased the size of each array to 100 elements and re-ran the test:

我将每个数组的大小增加到100个元素,并重新运行测试:

  1. New Byte Array using System.Array.Copy - 0.2812554 seconds
  2. 新的字节数组使用System.Array。复制- 0.2812554秒
  3. New Byte Array using System.Buffer.BlockCopy - 0.2500048 seconds
  4. 使用System.Buffer的新字节数组。BlockCopy - 0.2500048秒
  5. IEnumerable<byte> using C# yield operator - 0.0625012 seconds
  6. IEnumerable ,使用c#屈服算子- 0.0625012秒
  7. IEnumerable<byte> using LINQ's Concat<> - 0.0781265 seconds
  8. 使用LINQ的Concat<> - 0.0781265秒的IEnumerable

I increased the size of each array to 1000 elements and re-ran the test:

我将每个数组的大小增加到1000个元素并重新运行测试:

  1. New Byte Array using System.Array.Copy - 1.0781457 seconds
  2. 新的字节数组使用System.Array。复制- 1.0781457秒
  3. New Byte Array using System.Buffer.BlockCopy - 1.0156445 seconds
  4. 使用System.Buffer的新字节数组。BlockCopy - 1.0156445秒
  5. IEnumerable<byte> using C# yield operator - 0.0625012 seconds
  6. IEnumerable ,使用c#屈服算子- 0.0625012秒
  7. IEnumerable<byte> using LINQ's Concat<> - 0.0781265 seconds
  8. 使用LINQ的Concat<> - 0.0781265秒的IEnumerable

Finally, I increased the size of each array to 1 million elements and re-ran the test, executing each loop only 4000 times:

最后,我将每个数组的大小增加到100万个元素,并重新运行测试,每个循环只执行4000次:

  1. New Byte Array using System.Array.Copy - 13.4533833 seconds
  2. 新的字节数组使用System.Array。复制- 13.4533833秒
  3. New Byte Array using System.Buffer.BlockCopy - 13.1096267 seconds
  4. 使用System.Buffer的新字节数组。BlockCopy - 13.1096267秒
  5. IEnumerable<byte> using C# yield operator - 0 seconds
  6. IEnumerable ,使用c#屈服算子- 0秒
  7. IEnumerable<byte> using LINQ's Concat<> - 0 seconds
  8. IEnumerable ,使用LINQ的Concat<> - 0秒

So, if you need a new byte array, use

因此,如果需要一个新的字节数组,请使用

byte[] rv = new byte[a1.Length + a2.Length + a3.Length];
System.Buffer.BlockCopy(a1, 0, rv, 0, a1.Length);
System.Buffer.BlockCopy(a2, 0, rv, a1.Length, a2.Length);
System.Buffer.BlockCopy(a3, 0, rv, a1.Length + a2.Length, a3.Length);

But, if you can use an IEnumerable<byte>, DEFINITELY prefer LINQ's Concat<> method. It's only slightly slower than the C# yield operator, but is more concise and more elegant.

但是,如果您可以使用IEnumerable ,那么一定要使用LINQ的Concat<>方法。它只比c# yield运算符慢一点,但更简洁、更优雅。

IEnumerable<byte> rv = a1.Concat(a2).Concat(a3);

If you have an arbitrary number of arrays and are using .NET 3.5, you can make the System.Buffer.BlockCopy solution more generic like this:

如果你有任意数量的数组并且正在使用。net 3.5,你可以创建System.Buffer。块拷贝解决方案更通用如下:

private byte[] Combine(params byte[][] arrays)
{
    byte[] rv = new byte[arrays.Sum(a => a.Length)];
    int offset = 0;
    foreach (byte[] array in arrays) {
        System.Buffer.BlockCopy(array, 0, rv, offset, array.Length);
        offset += array.Length;
    }
    return rv;
}

*Note: The above block requires you adding the following namespace at the the top for it to work.

*注意:上面的块要求您在顶部添加以下名称空间以使其工作。

using System.Linq;

To Jon Skeet's point regarding iteration of the subsequent data structures (byte array vs. IEnumerable<byte>), I re-ran the last timing test (1 million elements, 4000 iterations), adding a loop that iterates over the full array with each pass:

对于Jon Skeet关于后续数据结构(字节数组对IEnumerable )的迭代的观点,我重新运行了最后一次计时测试(100万元素,4000次迭代),并添加一个循环,遍历整个数组,每个遍历:

  1. New Byte Array using System.Array.Copy - 78.20550510 seconds
  2. 新的字节数组使用System.Array。复制- 78.20550510秒
  3. New Byte Array using System.Buffer.BlockCopy - 77.89261900 seconds
  4. 使用System.Buffer的新字节数组。BlockCopy - 77.89261900秒
  5. IEnumerable<byte> using C# yield operator - 551.7150161 seconds
  6. IEnumerable ,使用c# yield operator——551.7150161秒
  7. IEnumerable<byte> using LINQ's Concat<> - 448.1804799 seconds
  8. IEnumerable 使用LINQ的Concat<> - 448.1804799秒。

The point is, it is VERY important to understand the efficiency of both the creation and the usage of the resulting data structure. Simply focusing on the efficiency of the creation may overlook the inefficiency associated with the usage. Kudos, Jon.

关键是,理解创建和使用结果数据结构的效率非常重要。仅仅关注创建的效率可能会忽略与使用相关的低效率。荣誉,乔恩。

#2


122  

Many of the answers seem to me to be ignoring the stated requirements:

在我看来,许多答案似乎忽视了规定的要求:

  • The result should be a byte array
  • 结果应该是一个字节数组
  • It should be as efficient as possible
  • 它应该尽可能地有效

These two together rule out a LINQ sequence of bytes - anything with yield is going to make it impossible to get the final size without iterating through the whole sequence.

这两者一起排除了LINQ字节序列——任何带有yield的元素都不可能在不遍历整个序列的情况下获得最终大小。

If those aren't the real requirements of course, LINQ could be a perfectly good solution (or the IList<T> implementation). However, I'll assume that Superdumbell knows what he wants.

当然,如果这些不是真正的需求,LINQ可能是一个完美的解决方案(或者IList 实现)。然而,我假设超级哑铃知道他想要什么。

(EDIT: I've just had another thought. There's a big semantic difference between making a copy of the arrays and reading them lazily. Consider what happens if you change the data in one of the "source" arrays after calling the Combine (or whatever) method but before using the result - with lazy evaluation, that change will be visible. With an immediate copy, it won't. Different situations will call for different behaviour - just something to be aware of.)

(编辑:我有另外一个想法。复制数组和延迟读取数组之间存在很大的语义差异。考虑一下,如果您在调用Combine(或其他)方法之后,在其中一个“源”数组中更改了数据,但是在使用结果之前(使用惰性计算),那么更改将是可见的。有了即时拷贝,它就不会了。不同的情况需要不同的行为——只是需要注意一些事情。

Here are my proposed methods - which are very similar to those contained in some of the other answers, certainly :)

以下是我提出的方法,它们与其他一些答案中包含的方法非常相似。

public static byte[] Combine(byte[] first, byte[] second)
{
    byte[] ret = new byte[first.Length + second.Length];
    Buffer.BlockCopy(first, 0, ret, 0, first.Length);
    Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
    return ret;
}

public static byte[] Combine(byte[] first, byte[] second, byte[] third)
{
    byte[] ret = new byte[first.Length + second.Length + third.Length];
    Buffer.BlockCopy(first, 0, ret, 0, first.Length);
    Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
    Buffer.BlockCopy(third, 0, ret, first.Length + second.Length,
                     third.Length);
    return ret;
}

public static byte[] Combine(params byte[][] arrays)
{
    byte[] ret = new byte[arrays.Sum(x => x.Length)];
    int offset = 0;
    foreach (byte[] data in arrays)
    {
        Buffer.BlockCopy(data, 0, ret, offset, data.Length);
        offset += data.Length;
    }
    return ret;
}

Of course the "params" version requires creating an array of the byte arrays first, which introduces extra inefficiency.

当然,“params”版本需要首先创建字节数组数组的数组,这会带来额外的效率低下。

#3


26  

If you simply need a new byte array, then use the following:

如果您只是需要一个新的字节数组,那么使用以下命令:

byte[] Combine(byte[] a1, byte[] a2, byte[] a3)
{
    byte[] ret = new byte[a1.Length + a2.Length + a3.Length];
    Array.Copy(a1, 0, ret, 0, a1.Length);
    Array.Copy(a2, 0, ret, a1.Length, a2.Length);
    Array.Copy(a3, 0, ret, a1.Length + a2.Length, a3.Length);
    return ret;
}

Alternatively, if you just need a single IEnumerable, consider using the C# 2.0 yield operator:

或者,如果您只需要一个IEnumerable,可以考虑使用c# 2.0 yield算子:

IEnumerable<byte> Combine(byte[] a1, byte[] a2, byte[] a3)
{
    foreach (byte b in a1)
        yield return b;
    foreach (byte b in a2)
        yield return b;
    foreach (byte b in a3)
        yield return b;
}

#4


26  

I took Matt's LINQ example one step further for code cleanliness:

为了使代码更整洁,我进一步使用了Matt的LINQ示例:

byte[] rv = a1.Concat(a2).Concat(a3).ToArray();

In my case, the arrays are small, so I'm not concerned about performance.

在我的例子中,数组很小,所以我不关心性能。

#5


8  

I actually ran into some issues with using Concat... (with arrays in the 10-million, it actually crashed).

实际上我在使用Concat时遇到了一些问题。(数组在1000万,它实际上崩溃了)。

I found the following to be simple, easy and works well enough without crashing on me, and it works for ANY number of arrays (not just three) (It uses LINQ):

我发现下面的内容简单、容易,并且在不影响我的情况下工作得很好,并且它适用于任意数量的数组(而不仅仅是三个)(它使用LINQ):

public static byte[] ConcatByteArrays(params byte[][]  arrays)
{
    return arrays.SelectMany(x => x).ToArray();
}

#6


5  

The memorystream class does this job pretty nicely for me. I couldn't get the buffer class to run as fast as memorystream.

memorystream类对我来说做得很好。我无法让缓冲区类像memorystream一样快地运行。

using (MemoryStream ms = new MemoryStream())
{
  ms.Write(BitConverter.GetBytes(22),0,4);
  ms.Write(BitConverter.GetBytes(44),0,4);
  ms.ToArray();
}

#7


2  

    public static bool MyConcat<T>(ref T[] base_arr, ref T[] add_arr)
    {
        try
        {
            int base_size = base_arr.Length;
            int size_T = System.Runtime.InteropServices.Marshal.SizeOf(base_arr[0]);
            Array.Resize(ref base_arr, base_size + add_arr.Length);
            Buffer.BlockCopy(add_arr, 0, base_arr, base_size * size_T, add_arr.Length * size_T);
        }
        catch (IndexOutOfRangeException ioor)
        {
            MessageBox.Show(ioor.Message);
            return false;
        }
        return true;
    }

#8


2  

    public static byte[] Concat(params byte[][] arrays) {
        using (var mem = new MemoryStream(arrays.Sum(a => a.Length))) {
            foreach (var array in arrays) {
                mem.Write(array, 0, array.Length);
            }
            return mem.ToArray();
        }
    }

#9


1  

Here's a generalization of the answer provided by @Jon Skeet. It is basically the same, only it is usable for any type of array, not only bytes:

下面是对@Jon Skeet提供的答案的概括。它基本上是一样的,只是适用于任何类型的数组,而不仅仅是字节:

public static T[] Combine<T>(T[] first, T[] second)
{
    T[] ret = new T[first.Length + second.Length];
    Buffer.BlockCopy(first, 0, ret, 0, first.Length);
    Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
    return ret;
}

public static T[] Combine<T>(T[] first, T[] second, T[] third)
{
    T[] ret = new T[first.Length + second.Length + third.Length];
    Buffer.BlockCopy(first, 0, ret, 0, first.Length);
    Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
    Buffer.BlockCopy(third, 0, ret, first.Length + second.Length,
                     third.Length);
    return ret;
}

public static T[] Combine<T>(params T[][] arrays)
{
    T[] ret = new T[arrays.Sum(x => x.Length)];
    int offset = 0;
    foreach (T[] data in arrays)
    {
        Buffer.BlockCopy(data, 0, ret, offset, data.Length);
        offset += data.Length;
    }
    return ret;
}

#10


0  

Can use generics to combine arrays. Following code can easily be expanded to three arrays. This way you never need to duplicate code for different type of arrays. Some of the above answers seem overly complex to me.

可以使用泛型组合数组。下面的代码可以很容易地扩展为三个数组。这样,您就不需要为不同类型的数组重复代码。在我看来,上面的一些答案似乎过于复杂。

private static T[] CombineTwoArrays<T>(T[] a1, T[] a2)
    {
        T[] arrayCombined = new T[a1.Length + a2.Length];
        Array.Copy(a1, 0, arrayCombined, 0, a1.Length);
        Array.Copy(a2, 0, arrayCombined, a1.Length, a2.Length);
        return arrayCombined;
    }

#11


-1  

All you need to pass list of Byte Arrays and this function will return you the Array of Bytes (Merged). This is the best solution i think :).

您只需传递字节数组的列表,此函数将返回字节数组(合并)。我认为这是最好的解决办法。

public static byte[] CombineMultipleByteArrays(List<byte[]> lstByteArray)
        {
            using (var ms = new MemoryStream())
            {
                using (var doc = new iTextSharp.text.Document())
                {
                    using (var copy = new PdfSmartCopy(doc, ms))
                    {
                        doc.Open();
                        foreach (var p in lstByteArray)
                        {
                            using (var reader = new PdfReader(p))
                            {
                                copy.AddDocument(reader);
                            }
                        }

                        doc.Close();
                    }
                }
                return ms.ToArray();
            }
        }

#12


-5  

Concat is the right answer, but for some reason a handrolled thing is getting the most votes. If you like that answer, perhaps you'd like this more general solution even more:

Concat是正确的答案,但是出于某种原因,手卷的东西获得的选票最多。如果你喜欢这个答案,也许你会更喜欢这个更普遍的答案:

    IEnumerable<byte> Combine(params byte[][] arrays)
    {
        foreach (byte[] a in arrays)
            foreach (byte b in a)
                yield return b;
    }

which would let you do things like:

这样你就能做到:

    byte[] c = Combine(new byte[] { 0, 1, 2 }, new byte[] { 3, 4, 5 }).ToArray();