Pages

Advertisement

Thursday, July 12, 2007

Understanding System.Buffer Class

Before we try out something with the Buffer class, you should understand the Buffer class and its Members. The first question that comes to mind is how they are different from the Array class and how they work as compared to the Array class.

Introduction:

Before we try out something with the Buffer class, you should understand the Buffer class and its Members. The first question that comes to mind is how they are different from the Array class and how they work as compared to the Array class.

This article is basically to answer the above questions and to help you understand how the Buffer class works. The word Buffer implies that the class works on direct Memory. In .Net it's basically a manipulation of unmanaged memory represented as arrays of bytes. So lets take a example of a program where we will copy one array data into another using the Array class as the first example and then compare it with a Buffer class example.

In System.Array we have a Copy() Member to copy from one array to another. Let's take an example with an array of five elements: Myarr1[5]. This array will be initialized with data 1, 2, 3, 4, and 5 and another array of ten elements called Myarr2[10] with contain data 0, 0, 0, 0, 0, 6, 7, 8, 9, 10.

The length of an array is the same as the number of elements in the array. In our example Myarr1 has five elements so array length is 5. Myarr2 has ten elements so the array length is 10. The Array class has a Copy() method which copies the contents of one array into another. It can copy a range of elements from an array starting at the specified source index and pastes them to another array starting at the specified destination index. So, the Copy() method takes five parameters. They are source array, source index, destination array, destination index, and the number of elements to copy.

Note: I am taking array index starting from 1 for better understanding in examples

Before Array.Copy() operation:

Myarr1[1]  Myarr1[2]  Myarr1[3]  Myarr3[4]  Myarr4[5]
1(data) 2(data) 3(data) 4(data) 5(data)

Myarr2[1] Myarr2[2] Myarr2[3] Myarr2[4] Myarr2[5]
0(data) 0(data) 0(data) 0(data) 0(data)

Myarr2[6] Myarr2[7] Myarr2[8] Myarr2[9] Myarr2[10]
6(data) 7(data) 8(data) 9(data) 10(data)

After Array.Copy() operation:

Myarr1[1]  Myarr1[2]  Myarr1[3]  Myarr3[4]  Myarr4[5]
1(data) 2(data) 3(data) 4(data) 5(data)

Myarr2[1] Myarr2[2] Myarr2[3] Myarr2[4] Myarr2[5]
1(data) 2(data) 3(data) 4(data) 5(data)

Myarr2[6] Myarr2[7] Myarr2[8] Myarr2[9] Myarr2[10]
6(data) 7(data) 8(data) 9(data) 10(data)

Here is the program for using Array.Copy():

Example 1:

namespace ConsoleApplication1
{
class Array1
{
static void
Main(string[] args)
{
int[] myarr1 = new int[5] {1,2,3,4,5};
int[] myarr2 = new int[10] {0,0,0,0,0,6,7,8,9,10};

Console.Write("Before Array copy operation\n");

Console.Write("Myarr1 and Byte Length{0}\n",myarr1.Length);
foreach(int i in myarr1)
Console.Write("{0} \t",i);

Console.WriteLine("\nMyarr2 and Byte Length:{0} \n",myarr2.Length);
foreach(int i in myarr2)
Console.Write("{0} \t",i);


//here we are copying index to index as data
Array.Copy(myarr1,0,myarr2,0,5);

Console.Write("After Array copy operation\n");

Console.Write("Myarr1:\n");

foreach(int i in myarr1)
Console.Write("{0} \t",i);

Console.WriteLine("\nMyarr2: \n");
foreach(int i in myarr2)
Console.Write("{0} \t",i);

//just for wait
Console.ReadLine();
}

}
}

Output:

Before Array Copy operation:
Myarr1 and Byte Length :5
1 2 3 4 5
Myarr2 and Byte Length:10
0 0 0 0 0 6 7 8 9 10
After Array Copy operation
Myarr1 :
1 2 3 4 5
Myarr2:
1 2 3 4 5 6 7 8 9 10

Now we will see same thing can be done using the System.Buffer class using the BlockCopy() method. But its not an index to index copy in the Buffer class. It's from offset to offset. The Buffer class copies a specified number of bytes from a source array starting at a particular offset to a destination array starting at a particular offset. Since we have taken integer arrays as example and we know int occupies four bytes. So offset values will be addition of 4 bytes from starting offset value.

In the System.Buffer class we have the BlockCopy() Member to copy from one array to another. Let's take an example with a array of five elements caled Myarr1[5]. This array is initialized with data 1, 2, 3, 4, 5. Another array of 10 elements called Myarr2[10] will be initialized with with data 0, 0, 0, 0, 0, 6, 7, 8, 9, 10.

In Buffer class the length means number of byte length in array. In our example Myarr1 has five elements so byte length is 5 (elements) x 4 (bytes of int)= 20 bytes. Myarr2 has ten elements so the byte length is 10 (elements) x 4 (bytes of int) = 40 bytes.

Buffer.ByteLength(Myarr1).

The Buffer class has the BlockCopy() method which copies one array content into another. It Copies a range of elements from an Array starting at the specified source start offset value and copies them to another Array starting at the specified destination offset value. So the BlockCopy() method takes five parameters. They are source array, source offset value, destination array, destination offset value, and the number of bytes to copy ( in our example we need to copy 5 elements then 5 x 4 = 20 bytes is the number of bytes to copy).

Before Buffer.BulkCopy() operation:

  Myarr1[1]     Myarr1[2]     Myarr1[3]      Myarr1[4]       Myarr1[5]
1 to 4 bytes 4 to 8 bytes 8 to 12 bytes 12 to 16 bytes 16 to 20 bytes
1(data) 2(data) 3(data) 4(data) 5(data)


Myarr2[1] Myarr2[2] Myarr2[3] Myarr2[4] Myarr2[5]
1-4 bytes 4-8 bytes 8-12 bytes 12-16 bytes 16-20 bytes
0(data) 0(data) 0(data) 0(data) 0(data)

Myarr2[6] Myarr2[7] Myarr2[8] Myarr2[9] Myarr2[10]
20-24bytes 24-28bytes 28-32bytes 32-26bytes 36-40bytes
6(data) 7(data) 8(data) 9(data) 10(data)

After Buffer.BulkCopy() operation:

  Myarr1[1]     Myarr1[2]     Myarr1[3]      Myarr1[4]       Myarr1[5]
1 to 4 bytes 4 to 8 bytes 8 to 12 bytes 12 to 16 bytes 16 to 20 bytes
1(data) 2(data) 3(data) 4(data) 5(data)

Myarr2[1] Myarr2[2] Myarr2[3] Myarr2[4] Myarr2[5]
1-4 bytes 4-8 bytes 8-12 bytes 12-16 bytes 16-20 bytes
1(data) 2(data) 3(data) 4(data) 5(data)

Myarr2[6] Myarr2[7] Myarr2[8] Myarr2[9] Myarr2[10]
20-24bytes 24-28bytes 28-32bytes 32-26bytes 36-40bytes
6(data) 7(data) 8(data) 9(data) 10(data)

Here is the program for using Buffer.BlockCopy():

Example 2:

using System;
namespace ConsoleApplication1
{
class buffer1
{
static void Main(string[] args)
{
int[] myarr1 = new int[5] {1,2,3,4,5};
int[] myarr2=new int[10] {0,0,0,0,0,6,7,8,9,10};

Console.Write("Before Block copy operation\n");
Console.Write("Myarr1 and Byte Length :{0}\n",
Buffer.ByteLength(myarr1));

foreach(int i in myarr1)
Console.Write("{0} \t",i);

Console.WriteLine("\nMyarr2 and Byte Length:{0} \n",
Buffer.ByteLength(myarr2));

foreach(int i in myarr2)
Console.Write("{0} \t",i);

//here we are copying offset to offet as bytes
Buffer.BlockCopy(myarr1,0,myarr2,0,20);

Console.Write("After Block copy operation\n");

Console.Write("Myarr1 :\n");
foreach(int i in myarr1)
Console.Write("{0} \t",i);

Console.WriteLine("\nMyarr2: \n");
foreach(int i in myarr2)
Console.Write("{0} \t",i);

//just for wait
Console.ReadLine();
}
}
}

Output:

Before Block Copy operation

Myarr1 and Byte Length :20
1 2 3 4 5

Myarr2 and Byte Length:40
0 0 0 0 0 6 7 8 9 10

After Block Copy operation

Myarr1 :
1 2 3 4 5

Myarr2:
1 2 3 4 5 6 7 8 9 10

If you observe both examples, you'll see that they give the same result but the way they operate is completely different. In the first example, you use Array.Copy(myarr1,0,myarr2,0,5);--> here 5 means the number array elements to copy. In example 2 you used Buffer.BlockCopy(myarr1,0,myarr2,0,20);--> here 20 means the number of bytes to copy. Five elements of type int occupy 20 bytes.

Downloads
Download source - 1 Kb

No comments:

Post a Comment