System.Buffer.BlockCopy 操作数组的用法

本文深入探讨了C#中Buffer.BlockCopy方法的使用,详细解释了如何将指定数量的字节从源数组复制到目标数组,包括参数、异常处理和示例代码。通过具体示例展示了数组操作技巧,适合C#开发者学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.官方解释及例子

Buffer.BlockCopy(Array, Int32, Array, Int32, Int32)
将指定数目的字节从起始于特定偏移量的源数组复制到起始于特定偏移量的目标数组。

public static void BlockCopy (Array src, int srcOffset, Array dst, int dstOffset, int count);

参数

src Array
源缓冲区。

srcOffset Int32
src 中的字节偏移量,从零开始。

dst Array
目标缓冲区。

dstOffset Int32
dst 中的字节偏移量,从零开始。

count Int32
要复制的字节数。

异常

ArgumentNullException
src 或 dst 为 null。

ArgumentException
src 或 dst 不是基元数组。
-或 - src 中的字节数小于 srcOffset 加上count 之和。
或 dst 中的字节数小于 dstOffset 加上count 之和。

ArgumentOutOfRangeException
srcOffset、dstOffset 或 count 小于 0。

示例

下面的示例使用BlockCopy方法复制数组的区域。 对于每BlockCopy个操作, 它将源数组和目标数组同时作为值数组和字节序列列出。 该示例说明了在使用BlockCopy方法时考虑系统的字节序的重要性:由于 Windows 系统不是字节序, 因此基元数据类型的值的低序位字节优先于高阶字节。

using System;

class Example
{
    // Display the individual bytes in the array in hexadecimal.
    public static void DisplayArray(Array arr, string name)
    {
        Console.WindowWidth = 120;
        Console.Write("{0,11}:", name);
        for (int ctr = 0; ctr < arr.Length; ctr++)
        {
            byte[] bytes;
            if (arr is long[])
               bytes = BitConverter.GetBytes((long) arr.GetValue(ctr));
            else
               bytes = BitConverter.GetBytes((short) arr.GetValue(ctr));
            
            foreach (byte byteValue in bytes)
               Console.Write(" {0:X2}", byteValue);
        }
        Console.WriteLine();
    }

    // Display the individual array element values in hexadecimal.
    public static void DisplayArrayValues(Array arr, string name)
    {
        // Get the length of one element in the array.
        int elementLength = Buffer.ByteLength(arr) / arr.Length;
        string formatString = String.Format(" {{0:X{0}}}", 2 * elementLength);
        Console.Write( "{0,11}:", name);
        for (int ctr = 0; ctr < arr.Length; ctr++)
            Console.Write(formatString, arr.GetValue(ctr));

        Console.WriteLine();
    }

    public static void Main( )
    {
        // These are the source and destination arrays for BlockCopy.
        short[] src  = { 258, 259, 260, 261, 262, 263, 264, 
                          265, 266, 267, 268, 269, 270 };
        long[] dest = { 17, 18, 19, 20 };

        // Display the initial value of the arrays in memory.
        Console.WriteLine( "Initial values of arrays:");
        Console.WriteLine("   Array values as Bytes:");
        DisplayArray(src, "src" );
        DisplayArray(dest, "dest");
        Console.WriteLine("   Array values:");
        DisplayArrayValues(src, "src");
        DisplayArrayValues(dest, "dest");
        Console.WriteLine();

        // Copy bytes 5-10 from source to index 7 in destination and display the result.
        Buffer.BlockCopy(src, 5, dest, 7, 6);
        Console.WriteLine("Buffer.BlockCopy(src, 5, dest, 7, 6 )");
        Console.WriteLine("   Array values as Bytes:");
        DisplayArray(src, "src");
        DisplayArray(dest, "dest");
        Console.WriteLine("   Array values:");
        DisplayArrayValues(src, "src");
        DisplayArrayValues(dest, "dest");
        Console.WriteLine();
        
        // Copy bytes 16-20 from source to index 22 in destination and display the result. 
        Buffer.BlockCopy(src, 16, dest, 22, 5);
        Console.WriteLine("Buffer.BlockCopy(src, 16, dest, 22, 5)");
        Console.WriteLine("   Array values as Bytes:");
        DisplayArray(src, "src");
        DisplayArray(dest, "dest");
        Console.WriteLine("   Array values:");
        DisplayArrayValues(src, "src");
        DisplayArrayValues(dest, "dest");
        Console.WriteLine();
         
        // Copy overlapping range of bytes 4-10 to index 5 in source.
        Buffer.BlockCopy(src, 4, src, 5, 7 );
        Console.WriteLine("Buffer.BlockCopy( src, 4, src, 5, 7)");
        Console.WriteLine("   Array values as Bytes:");
        DisplayArray(src, "src");
        DisplayArray(dest, "dest");
        Console.WriteLine("   Array values:");
        DisplayArrayValues(src, "src");
        DisplayArrayValues(dest, "dest");
        Console.WriteLine();
        
        // Copy overlapping range of bytes 16-22 to index 15 in source. 
        Buffer.BlockCopy(src, 16, src, 15, 7);
        Console.WriteLine("Buffer.BlockCopy( src, 16, src, 15, 7)");
        Console.WriteLine("   Array values as Bytes:");
        DisplayArray(src, "src");
        DisplayArray(dest, "dest");
        Console.WriteLine("   Array values:");
        DisplayArrayValues(src, "src");
        DisplayArrayValues(dest, "dest");
    }
}
// The example displays the following output:
//    Initial values of arrays:
//       Array values as Bytes:
//            src: 02 01 03 01 04 01 05 01 06 01 07 01 08 01 09 01 0A 01 0B 01 0C 01 0D 01 0E 01
//           dest: 11 00 00 00 00 00 00 00 12 00 00 00 00 00 00 00 13 00 00 00 00 00 00 00 14 00 00 00 00 00 00 00
//       Array values:
//            src: 0102 0103 0104 0105 0106 0107 0108 0109 010A 010B 010C 010D 010E
//           dest: 0000000000000011 0000000000000012 0000000000000013 0000000000000014
//    
//    Buffer.BlockCopy(src, 5, dest, 7, 6 )
//       Array values as Bytes:
//            src: 02 01 03 01 04 01 05 01 06 01 07 01 08 01 09 01 0A 01 0B 01 0C 01 0D 01 0E 01
//           dest: 11 00 00 00 00 00 00 01 05 01 06 01 07 00 00 00 13 00 00 00 00 00 00 00 14 00 00 00 00 00 00 00
//       Array values:
//            src: 0102 0103 0104 0105 0106 0107 0108 0109 010A 010B 010C 010D 010E
//           dest: 0100000000000011 0000000701060105 0000000000000013 0000000000000014
//    
//    Buffer.BlockCopy(src, 16, dest, 22, 5)
//       Array values as Bytes:
//            src: 02 01 03 01 04 01 05 01 06 01 07 01 08 01 09 01 0A 01 0B 01 0C 01 0D 01 0E 01
//           dest: 11 00 00 00 00 00 00 01 05 01 06 01 07 00 00 00 13 00 00 00 00 00 0A 01 0B 01 0C 00 00 00 00 00
//       Array values:
//            src: 0102 0103 0104 0105 0106 0107 0108 0109 010A 010B 010C 010D 010E
//           dest: 0100000000000011 0000000701060105 010A000000000013 00000000000C010B
//    
//    Buffer.BlockCopy( src, 4, src, 5, 7)
//       Array values as Bytes:
//            src: 02 01 03 01 04 04 01 05 01 06 01 07 08 01 09 01 0A 01 0B 01 0C 01 0D 01 0E 01
//           dest: 11 00 00 00 00 00 00 01 05 01 06 01 07 00 00 00 13 00 00 00 00 00 0A 01 0B 01 0C 00 00 00 00 00
//       Array values:
//            src: 0102 0103 0404 0501 0601 0701 0108 0109 010A 010B 010C 010D 010E
//           dest: 0100000000000011 0000000701060105 010A000000000013 00000000000C010B
//    
//    Buffer.BlockCopy( src, 16, src, 15, 7)
//       Array values as Bytes:
//            src: 02 01 03 01 04 04 01 05 01 06 01 07 08 01 09 0A 01 0B 01 0C 01 0D 0D 01 0E 01
//           dest: 11 00 00 00 00 00 00 01 05 01 06 01 07 00 00 00 13 00 00 00 00 00 0A 01 0B 01 0C 00 00 00 00 00
//       Array values:
//            src: 0102 0103 0404 0501 0601 0701 0108 0A09 0B01 0C01 0D01 010D 010E
//           dest: 0100000000000011 0000000701060105 010A000000000013 00000000000C010B

注解

此方法将count从开始src, 从srcOffset dst开始复制个字节。 dstOffset srcOffset 和dstOffset都是从零开始的; 也就是说, 每个缓冲区中的第一个字节位于位置 0, 而不是位置1。

方法使用偏移量访问src参数数组中的字节, 而不是编程构造 (如索引或数组上限和下限数组界限)。 BlockCopy 例如, 如果您的应用程序的编程语言中声明Int32的数组的50下限为从零开始, 然后将该数组和偏移量5传递BlockCopy给方法, 则该方法将访问的第一个数组元素是第二个数组的元素, 该元素的索引为-49。 此外, 首先访问数组元素49的哪个字节取决于正在执行应用程序的计算机的字节排序。

顾名思义, BlockCopy方法会将字节块作为一个整体复制, 而不是一次复制一个字节。 因此, 如果src和dst引用相同的数组 + count srcOffset + dstOffset , 并且-1 范围内的范围与-1 重叠, 则重叠的值count将字节复制到目标之前, 不会覆盖这些字节。 在下面的示例中, 名arr为的数组中字节0-16 的值将复制到字节12-28。 尽管存在重叠的范围, 但源字节的值已成功复制。

const int INT_SIZE = 4;
int[] arr = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
Buffer.BlockCopy(arr, 0 * INT_SIZE, arr, 3 * INT_SIZE, 4 * INT_SIZE);
foreach (int value in arr)
   Console.Write("{0}  ", value);
// The example displays the following output:
//       2  4  6  2  4  6  8  16  18  20

在下面的示例中, 名arr为的数组中字节12-28 的值将复制到字节0-16。 同样, 无论重叠范围如何, 都可以成功复制源字节的值。

const int INT_SIZE = 4;
int[] arr = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
Buffer.BlockCopy(arr, 3 * INT_SIZE, arr, 0 * INT_SIZE, 4 * INT_SIZE);
foreach (int value in arr)
   Console.Write("{0}  ", value);
// The example displays the following output:
//       8  10  12  14  10  12  14  16  18  20

2. 截取数组操作举例

工作中使用的到的截取,加自己的理解,记录

public static void BlockCopy (Array src, int srcOffset, Array dst, int dstOffset, int count);

src 原始数组。下面例子中的 src
srcOffset 原始数组中的偏移量,从零开始。原始数组开始操作的下标
dst 目标数组。下面例子中的 dst
dstOffset 目标数组中的字节偏移量,从零开始。目标数组开始操作的下标
count 要复制的字节数。操作的数量长度
例子

 		byte[] src= new byte[] { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
        byte[] dst = new byte[3];
        //从src截取前3个放到dst数组里面
        System.Buffer.BlockCopy(src, 0, dst, 0, 3);
        Debug.Log(System.BitConverter.ToString(src)); //02-04-06-08-0A-0C-0E-10-12-14
        Debug.Log(System.BitConverter.ToString(dst)); //02-04-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值