Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中组合两个或多个字节数组的最佳方法#_C#_Arrays - Fatal编程技术网

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

C# 在C中组合两个或多个字节数组的最佳方法#,c#,arrays,C#,Arrays,我有3个C#字节数组,需要合并成一个。完成此任务最有效的方法是什么?如果您只需要一个新的字节数组,请使用以下方法: 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,

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

如果您只需要一个新的字节数组,请使用以下方法:

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;
}

可选地,如果只需要一个iQueDaby,考虑使用C 2屈服算符:

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;
}
IEnumerable联合收割机(字节[]a1、字节[]a2、字节[]a3)
{
foreach(a1中的字节b)
收益率b;
foreach(a2中的字节b)
收益率b;
foreach(a3中的字节b)
收益率b;
}
对于基本类型(包括字节),请使用而不是。它更快

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

  • 使用
    System.Array.Copy
    新建字节数组-0.2187556秒
  • 使用
    System.Buffer.BlockCopy
    的新字节数组-0.1406286秒
  • 使用C#屈服运算符的IEnumerable-0.0781270秒
  • 使用LINQ的Concat-0.0781270秒计算
  • 我将每个阵列的大小增加到100个元素,然后重新运行测试:

  • 使用
    System.Array.Copy
    新建字节数组-0.2812554秒
  • 使用
    System.Buffer.BlockCopy
    的新字节数组-0.2500048秒
  • 使用C#屈服运算符的IEnumerable-0.0625012秒
  • 使用LINQ的Concat-0.0781265秒计算
  • 我将每个阵列的大小增加到1000个元素,然后重新运行测试:

  • 使用
    System.Array.Copy
    -1.0781457秒新建字节数组
  • 使用
    System.Buffer.BlockCopy
    的新字节数组-1.0156445秒
  • 使用C#屈服运算符的IEnumerable-0.0625012秒
  • 使用LINQ的Concat-0.0781265秒计算
  • 最后,我将每个数组的大小增加到100万个元素,并重新运行测试,只执行每个循环4000次:

  • 使用
    System.Array.Copy
    新建字节数组-13.4533833秒
  • 使用
    System.Buffer.BlockCopy
    的新字节数组-13.1096267秒
  • 使用C#yield运算符的IEnumerable-0秒
  • 使用LINQ的Concat-0秒进行IEnumerable
  • 因此,如果需要新的字节数组,请使用

    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);
    
    但是,如果您可以使用
    IEnumerable
    肯定会选择LINQ的Concat方法。它只比C#yield操作符稍微慢一点,但更简洁、更优雅

    IEnumerable<byte> rv = a1.Concat(a2).Concat(a3);
    
    *注意:上面的块要求您在顶部添加以下名称空间,以使其工作

    using System.Linq;
    
    对于Jon Skeet关于后续数据结构迭代(字节数组vs.IEnumerable)的观点,我重新运行了上一次计时测试(100万个元素,4000次迭代),添加了一个循环,每次循环都在整个数组上迭代:

  • 使用
    System.Array.Copy
    -78.2050510秒新建字节数组
  • 使用
    System.Buffer.BlockCopy
    的新字节数组-77.89261900秒
  • 使用C#yield运算符的IEnumerable-551.7150161秒
  • 使用LINQ的Concat可计算-448.1804799秒

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

    康卡特是正确的答案,但出于某种原因,一件手工制作的东西获得了最多的选票。如果你喜欢这个答案,也许你更喜欢这个更普遍的解决方案:

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

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

    • 结果应该是一个字节数组
    • 它应该尽可能高效
    这两种方法一起排除了LINQ字节序列——任何具有
    yield
    的方法都将使不遍历整个序列就无法获得最终大小

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

    编辑:我刚刚有另一个想法。制作数组的副本和懒惰地读取它们之间有很大的语义差异。如果在调用<代码>组合< <代码>(或其他什么)之后,更改“源”数组中的一个数据,会发生什么情况?方法,但在使用结果之前-使用惰性计算,更改将可见。使用即时副本,更改将不可见。不同的情况将需要不同的行为-只是需要注意。)

    以下是我提出的方法——与其他一些答案中包含的方法非常相似,当然:)


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

    memorystream类对我来说做得非常好。我无法让buffer类像memorystream那样快速运行

    using (MemoryStream ms = new MemoryStream())
    {
      ms.Write(BitConverter.GetBytes(22),0,4);
      ms.Write(BitConverter.GetBytes(44),0,4);
      ms.ToArray();
    }
    
    public static bool MyConcat(参考T[]base\u arr,参考T[]add\u arr)
    {
    尝试
    {
    int base_size=base_arr.Length;
    int size_T=System.Runtime.InteropServices.Marshal.SizeOf(base_arr[0]);
    调整数组大小(参考基本数组、基本数组大小+添加数组长度);
    Buffer.BlockCopy(添加arr,0,基本arr,基本大小*size\T,添加arr.Length*size\T);
    }
    捕获(IndexOutOfRangeException ioor)
    {
    MessageBox.Show(ioor.Message);
    返回false;
    }
    返回true;
    }
    
    以下是@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;
    }
    
    公共静态T[]组合(T[]第一,T[]第二)
    {
    T[]ret=新的T[first.Length+second.Length];
    Buffer.BlockCopy(第一、0、ret
    
    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;
    }
    
    using (MemoryStream ms = new MemoryStream())
    {
      ms.Write(BitConverter.GetBytes(22),0,4);
      ms.Write(BitConverter.GetBytes(44),0,4);
      ms.ToArray();
    }
    
        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;
        }
    
    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;
    }
    
    byte[] rv = a1.Concat(a2).Concat(a3).ToArray();
    
        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();
            }
        }
    
    public static byte[] ConcatByteArrays(params byte[][]  arrays)
    {
        return arrays.SelectMany(x => x).ToArray();
    }
    
    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();
                }
            }
    
    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;
        }
    
        /// <summary>
        /// Combine two Arrays with offset and count
        /// </summary>
        /// <param name="src1"></param>
        /// <param name="offset1"></param>
        /// <param name="count1"></param>
        /// <param name="src2"></param>
        /// <param name="offset2"></param>
        /// <param name="count2"></param>
        /// <returns></returns>
        public static T[] Combine<T>(this T[] src1, int offset1, int count1, T[] src2, int offset2, int count2) 
            => Enumerable.Range(0, count1 + count2).Select(a => (a < count1) ? src1[offset1 + a] : src2[offset2 + a - count1]).ToArray();