C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
Note: This is useful for compression, images, or many other types of binary data.
ByteHere: The ints are actually used as bytes, not 4-byte ints. The byte array arr2 is automatically initialized to all zero bytes.
Byte ArrayC# program that uses BlockCopy on bytes
using System;
class Program
{
static void Main()
{
byte[] arr1 = new byte[] { 1, 2, 3, 4, 5 };
byte[] arr2 = new byte[10];
// Copy the first five bytes from arr1 to arr2
Buffer.BlockCopy(arr1, 0, arr2, 0, 5);
Display(arr2);
}
static void Display(byte[] arr)
{
for (int i = 0; i < arr.Length; i++)
{
Console.Write(arr[i]);
}
Console.WriteLine();
}
}
Output
1234500000
Note: We need to pass in the number of bytes to copy, not the array element count. We must multiply it by 4, or the sizeof(int).
Note 2: In this example, the sizeof() operator returns the byte length of a primitive data type like int. Here it returns 4.
And: The multiplication of sizeof(int) * 4 can be resolved by the C# compiler—it won't cause any slowdowns.
C# program that copies ints
using System;
class Program
{
static void Main()
{
int[] arr1 = new int[] { 1, 2, 3, 4, 5 };
int[] arr2 = new int[10];
// Copy the first twenty bytes from arr1 to arr2
Buffer.BlockCopy(arr1, 0, arr2, 0, 5 * sizeof(int));
Display(arr2);
}
static void Display(int[] arr)
{
for (int i = 0; i < arr.Length; i++)
{
Console.Write(arr[i]);
}
Console.WriteLine();
}
}
Output
1234500000
Note: We use Buffer.ByteLength to count the total number of bytes in each array. Each int is 4 bytes. Each byte is a single byte.
C# program that uses Buffer.ByteLength method
using System;
class Program
{
static void Main()
{
// Example arrays for program.
// ... Each array has three elements.
int[] array1 = { 1, 2, 3 };
byte[] array2 = { 1, 2, 3 };
// Get lengths of arrays.
// ... This counts the bytes in all elements.
int length1 = Buffer.ByteLength(array1);
int length2 = Buffer.ByteLength(array2);
// Write results.
Console.WriteLine(length1);
Console.WriteLine(length2);
}
}
Output
12
3
Note: By using GetByte and SetByte, we read and assign the individual bytes in each integer directly.
Tip: This changes the decimal representation of the integer by changing the bytes in the integer.
And: This is used to treat an integer array as a bitmask or other structure. One bit is used to indicate true or false.
True, FalseC# program that uses Buffer.GetByte and Buffer.SetByte
using System;
class Program
{
static void Main()
{
// Use an array of three integers for testing.
// ... Loop through the bytes in the array and write their values.
int[] array1 = { 1, 1, 256 };
for (int i = 0; i < Buffer.ByteLength(array1); i++)
{
Console.WriteLine(Buffer.GetByte(array1, i));
}
// Set certain byte values at indexes in the array.
Buffer.SetByte(array1, 0, 55);
Buffer.SetByte(array1, 4, 55);
Buffer.SetByte(array1, 8, 55);
// Render the modified array.
Console.WriteLine("---");
for (int i = 0; i < Buffer.ByteLength(array1); i++)
{
Console.WriteLine(Buffer.GetByte(array1, i));
}
}
}
Output
1
0
0
0
1
0
0
0
0
1
0
0
---
55
0
0
0
55
0
0
0
55
1
0
0
Version 1: This version of the code uses Buffer.BlockCopy on a 1000-element byte array. It tests the result for correctness.
Version 2: This version uses Array.Copy with similar arguments to the Buffer.BlockCopy version.
Result: Using Buffer.BlockCopy is consistently faster. For copying larger arrays of values, it should be preferred.
Also: Copying the elements in a for-loop was far slower. So using BlockCopy is a significant win.
Array.CopyForC# program that benchmarks Buffer.BlockCopy
using System;
using System.Diagnostics;
class Program
{
static byte[] GetSourceArray()
{
// Populate data.
var result = new byte[1000];
result[0] = 100;
result[999] = 1;
return result;
}
static bool IsValidData(byte[] data)
{
// Test data.
return data[0] == 100 &&
data[999] == 1;
}
const int _max = 10000000;
static void Main()
{
const int size = 1000;
byte[] source = GetSourceArray();
byte[] target = new byte[size];
// Version 1: use Buffer.BlockCopy.
var s1 = Stopwatch.StartNew();
for (int i = 0; i < _max; i++)
{
Buffer.BlockCopy(source, 0, target, 0, size);
if (!IsValidData(target))
{
return;
}
}
s1.Stop();
// Reset.
source = GetSourceArray();
target = new byte[size];
// Version 2: use Array.Copy.
var s2 = Stopwatch.StartNew();
for (int i = 0; i < _max; i++)
{
Array.Copy(source, target, size);
if (!IsValidData(target))
{
return;
}
}
s2.Stop();
Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) /
_max).ToString("0.00 ns"));
Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) /
_max).ToString("0.00 ns"));
}
}
Output
33.75 ns Buffer.BlockCopy
51.65 ns Array.Copy