Understanding System.Buffer Class

Environment: .Net SDK Beta 2 or Visual Studio .Net beta 2

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


Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Today's agile organizations pose operations teams with a tremendous challenge: to deploy new releases to production immediately after development and testing is completed. To ensure that applications are deployed successfully, an automatic and transparent process is required. We refer to this process as Zero Touch Deployment™. This white paper reviews two approaches to Zero Touch Deployment--a script-based solution and a release automation platform. The article discusses how each can solve the key …

  • On-demand Event Event Date: October 29, 2014 It's well understood how critical version control is for code. However, its importance to DevOps isn't always recognized. The 2014 DevOps Survey of Practice shows that one of the key predictors of DevOps success is putting all production environment artifacts into version control. In this webcast, Gene Kim discusses these survey findings and shares woeful tales of artifact management gone wrong! Gene also shares examples of how high-performing DevOps …

Most Popular Programming Stories

More for Developers

RSS Feeds