| Byte düzeyinde değişik 
tipteki dizi değişkenler üzerinde işlem yaparken System Namespace’te yer alan 
Buffer sınıfı işinizi kolaylaştırabilir. Bu işlemler yapılırken Buffer sınıfının 
BlockCopy() metodundan yararlanılmaktadır. 
Buffer sınıfının işlevini anlatan veya metotlarının nasıl kullanıldığını 
  gösteren örnek hazırlamadan önce Array sınıfının Copy() metodundan söz edeceğim. 
  Bu amaçla int tipinde farklı sayıda elemanlara sahip 2 dizi değişken tanımladım 
  ve ilk dizinin 3 elemanını Copy() metodu ile ikinciye aktardım. 
 
 
   
    | private void 
      Form1_Click(object sender, EventArgs e) {
 int[] Dizi_1 = {1,2,3,4};
 int[] Dizi_2 = {0,0,0,0,0};
 Array.Copy(Dizi_1, 0, Dizi_2, 0, 3);
 }
 |  Hatırlayacağınız gibi Array sınıfının Copy() metodu 1. parametre olarak verilen 
dizi değiş¬kenin istenilen elemanından itibaren istenilen sayıda elemanı 3. parametrede 
işaret edilen hedef diziye kopyalamaktadır. 
Bu kod işletildiğinde Copy() metodu ilk dizinin ilk 3 elemanının 
  içeriğini ikinci dizinin aynı elemanlarına aktarır ve Dizi_2’nin elemanları 
  sıra ile “1, 2, 3, 0, 0” değerlerini içerir. Aynı kopyalama işlemini Buffer 
  sınıfının BlockCopy() metodu ile yapabilirsiniz. Bu metodun nasıl kullanıldığını 
  aşağıda görebilirsiniz.
 
 
 
 
  Buffer sınıfının 
  BlockCopy() metodu bu şekilde kullanıldığında beklenenin aksine ilk TextBox’a 
  1, diğer TextBox’lara ise 0 aktarılır. Aşağıda verilen ekran görüntüsünü bu 
  kodu işlettikten sonra aldım. 
    | private void 
      Form1_Click(object sender, EventArgs e) {
 int[] Dizi_1 = {1,2,3,4};
 int[] Dizi_2 = {0,0,0,0};
 System.Buffer.BlockCopy(Dizi_1, 0, Dizi_2, 
      0, 3);
 textBox1.Text = Dizi_2[0].ToString();
 textBox2.Text = Dizi_2[1].ToString();
 textBox3.Text = Dizi_2[2].ToString();
 textBox4.Text = Dizi_2[3].ToString();
 }
 |  
 
   Çünkü BlockCopy() metodunu bu şekilde kullanmakla aslında şöyle bir talepte 
  bulunmuş oluyoruz: İlk dizinin ilk byte’ından başlamak üzere ikinci diziye 3 
  byte bilgi kopyala. Belki bu cümle karışık oldu. Şimdi buna açıklık getirmeye 
  çalışacağım. Madem int değiş¬kenler bellekte 4 byte yer kaplamaktadır int tipindeki 
  ilk dizi değişkenin bellekteki yerleşimi aşağıdaki gibi resmedilebilir.
 
 
  
 int değişkene aktardığım değerler küçük olduğu için en sağdaki byte’lar yeterli 
  olmaktadır. Bu 4 adet 32 bit bellekte arka arkaya dururlar. BlockCopy() metodunu 
  aşağıdaki gibi kullanmakla gerçekte ne demiş oluyoruz?
 
 System.Buffer.BlockCopy(Dizi_1, 0, Dizi_2, 0, 3);
 
 Bu 4*4=16 byte’ın 
  veya 4*4*8= 128 bitin ilk 3 byte’nı veya 8*3=24 bitini kopyala demiş oluyoruz. 
  Bizim örnekte ilk byte 1, 2. ve 3. byte’larda ise 0 bilgisi olduğu için yukarıda 
  verilen sonuç alınır. BlockCopy() metodu aşağıdaki gibi kullanılsaydı, başka 
  bir deyişle kaynak diziden hedef diziye 3 yerine 4 byte kopyalansaydı değişen 
  bir şey olmazdı.
 
 Çünkü temsili resimden 
  görebileceğiniz gibi int tipindeki kaynak dizinin ilk elemanın son byte’ının 
  bütün bitleri 0 ile doludur. Peki BlockCopy() metodu aşağıdaki gibi kullanılmış 
  olsaydı hedef dizi değişkenin elemanlarının içeriği ne olurdu?
 
 System.Buffer.BlockCopy(Dizi_1, 
  0, Dizi_2, 0, 5);
 
 4. parametre olarak 
  5 kullanıldığı için toplam 4 elemanı olan int tipindeki kaynak dizi değiş¬kenin 
  toplam 16 byte’ın ilk 5 byte veya ilk 40 biti hedef diziye kopyalanır. Kaynak 
  dizi değiş¬kenin 2. elemanı 2 değerini içeriği için sorunsuz bir şekilde 2. 
  elemanın içeriği hedef dizideki 2. elemana kopyalanır ve aşağıdaki gibi bir 
  sonuç alınır.
 
 
   
 Şimdi şeytanın avukatlığını yapıp kaynak dizi değişkenin başlangıçta 2 olan 
  içeriğini 256 yapacağım. Bu şartlarda BlockCopy() metodu ile kaynak dizinin 
  ilk 5 byte’ı okunup hedef diziye aktarılırsa ne olur?
 
 
 
  Bu şartlarda int 
  tipindeki kaynak dizi değişkenin 2. elamanın veya ikinci 32 bitinin bellek¬teki 
  temsili yerleşimi aşağıdaki gibi olur. Eleman 256 bilgisini içerdiği için 9. 
  bit hariç bütün bitler 0 değerini içerir. 
    | int[] Dizi_1 
      = {1,256,3,4}; int[] Dizi_2 = {0,0,0,0};
 System.Buffer.BlockCopy(Dizi_1, 0, Dizi_2, 0, 5);
 |  
 
  Bu durumda int tipindeki kaynak dizi değişkenden 5 byte veya 5*8=40 bit bilgi 
  okunursa hedef dizinin 2. elemanı 0 olarak kalmaya devam eder. Çünkü 0 olmayan 
  ilk bit 41. bitte bulunmaktadır. Bu şartlarda yukarıda verilen kod işletilirse 
  aşağıdaki gibi bir sonuç alınır.
 
 
   
 BlockCopy() metodu ile kaynak diziden 5*8=40 byte yerine 6*8=48 byte okunsaydı 
  hedef dizi değişkenin 2. elemanı 256 olurdu. Kaynak dizinin 2. elemanı 256 yerine 
  500 sayısını içeriyor olsaydı ve BlockCopy() metodu ile kaynak diziden 5*8=40 
  byte okunup hedef diziye aktarılmış olsaydı hedef dizinin 2. elamın içeriği 
  ne olurdu?
 
 Bu sorunun cevabını 
  yukarıda verdiğim ve BlockCopy() metodunun kullanıldığı kodu işlet¬meden bulmak 
  istiyorsanız Windows ile birlikte verilen Hesap Makinesi programını çalıştırıp 
  10 tabanlı 500 sayısının 2 tabanlı karşılığını öğrenerek bulabilirsiniz. 500 
  sayısını 2 tabanlı olarak ifade etmek için 9 bit yeterli olmaktadır(1 1 1 1 
  1 0 1 0 0).
 
 Kaynak dizi değişkenin 
  2. elemanı 500 sayısını içeriyorken BlockCopy() metodu ile 40 byte okursanız 
  hedef dizi değişkene, kaynak dizi değişkenin aynı sıradaki elemanın ilk 8 byte’ı 
  kopyalanır ve içeriği 224 olur. Çünkü 2 tabanlı “1 1 1 1 0 1 0 0” sayısının 
  10 tabanlı karşılığı 224’tür.
 
 
 
 
  Yukarıda belirtildiği 
  gibi int tipindeki kaynak dizi değişkenimiz 4 elemana sahiptir ve bellekte toplam 
  4*4=16 byte yer kapmaktadır. Eğer bu örnekte BlockCopy() metoduna 16’dan büyük 
  bir değeri 5. parametre olarak verirseniz hata meydana gelir. 
    | int[] Dizi_1 
      = {1,500,3,4}; int[] Dizi_2 = {0,0,0,0};
 System.Buffer.BlockCopy(Dizi_1, 0, Dizi_2, 0, 5);
 |  
 Yukarıda verdiğim 
  örnekte kaynak ve hedef dizi değişkenler aynı tipteydi. BlockCopy() metodu farklı 
  tipteki dizi değişkenleri parametre olarak alıp kopyalama yapabilmektedir. Bu 
  konuda bilgi vermek için birisi 2 byte’lık Short diğeri 1 Byte’lık byte tipinde 
  2 dizi değişken tanımladım.
 
 
 
 
  Bu şekilde tanımlanıp 
  2 elemanlı olması sağlanan short dizi değişken bellekte 2*2=4 byte veya 2*2*8=32 
  bit yer kaplar. Bu dizi değişkenin bellekteki yerleşimi aşağıdaki gibi olur. 
    | short[] Kaynak_Dizi 
      = {1000,2000}; byte[] Hedef_Dizi = new byte[10];
 |  
 
  
 Şimdi bu kaynak dizinin ilk 3 byte’nı veya 24 bitini BlockCopy()metodu ile okuyup 
  Byte tipindeki hedef diziye aktaracağım. Başka bir deyişle kaynak dizinin ilk 
  elamanın bütün bitlerini, 2. elemanın ise ilk 8 bitini okuyacağım.
 
 
 
 
   
    | short[] Kaynak_Dizi 
      = {1000,2000,3000}; byte[] Hedef_Dizi = new byte[10];
 System.Buffer.BlockCopy(Kaynak_Dizi, 0, Hedef_Dizi, 0, 3);
 |  BlockCopy() metodu bu şekilde kullanıldığında toplam 6 byte bilgi okunduğu için 
byte tipindeki hedef dizi değişkenin ilk 6 elemanı doldurulur. Bu elemanların 
içeriklerini size göstermek için forma TextBox’lar yerleştirdim ve aşağıda verdiğim 
kodu hazırladım.
 
 
 
  Bu kod işletildiğinde 
  2 bitlik kaynak dizinin ilk elemanın yarısı byte tipindeki hedef dizinin ilk 
  elemana, diğer yarısı ise 2. elemana aktarılır. Kaynak dizinin 2. elemanın ilk 
  byte’ı veya yarısı ise hedef dizideki 3. elemana aktarılır. Bu kod işletildiğinde 
  aşağıda verilen sonuç alınır. 
    | private void 
      Form1_Click(object sender, EventArgs e) {
 short[] Kaynak_Dizi = {1000,2000,3000};
 byte[] Hedef_Dizi = new byte[10];
 System.Buffer.BlockCopy(Kaynak_Dizi, 0, Hedef_Dizi, 
      0, 3);
 textBox1.Text = Hedef_Dizi[0].ToString();
 textBox2.Text = Hedef_Dizi[1].ToString();
 textBox3.Text = Hedef_Dizi[2].ToString();
 textBox4.Text = Hedef_Dizi[3].ToString();
 }
 |  
 
   
 Yukarıda verilen örneklerde kaynak dizinin eleman sayısını her elemanın bellekte 
  kapladığı byte miktarını kendim çarpıp hedef dizide gereken eleman sayısını 
  buldum. Ancak bu hesapların kod yazılarak yapılması gerekir. Buffer sınıfının 
  ByteLength() metodu parametre olarak aldığı dizi değişkenin bellekte kaç byte 
  yer kapladığını bulmaktadır. ByteLength() metodu aşağıdaki gibi kullanıldığında 
  geriye 4*10=40 sayısını gönderir.
 
 
 
 
  Buffer sınıfının 
  yukarıda sözü edilen BlockCopy() ve ByteLength() metotlarından başka ayrıca 
  GetByte() adında bir metodu bulunmaktadır. Bu metot istenen tipteki dizi değişkenin 
  istenen byte’nın içeriğini okumaya yaramaktadır. GetByte() metodunun nasıl kullanıldığını 
  aşağıda görebilirsiniz. 
    | private void 
      Form1_Click(object sender, EventArgs e) {
 int[] Dizi = new int[10];
 int sayi = System.Buffer.ByteLength(Dizi);
 textBox1.Text = sayi.ToString();
 }
 |  
 
 
  Bu örnekte GetByte() 
  metoduna parametre olarak 3 elemanlı short tipindeki dizi değişkeni verdim. 
  Short tipindeki bu dizi değişkenin her elamanı bellekte 2 byte yer kaplamakta 
  ve ilk elemana aktarılan sayı ilk byte’a sığdığı için ilk byte’ın içeriği eksiksiz 
  okunup ilk TextBox’a aktarılır. 
    | private void 
      Form1_Click(object sender, EventArgs e) {
 short[] Dizi = {100, 1000, 10000};
 int ilk_byte = Buffer.GetByte(Dizi, 0);
 int ikinci_byte = Buffer.GetByte(Dizi, 1);
 int ucuncu_byte = Buffer.GetByte(Dizi, 2);
 int dorduncu_byte = Buffer.GetByte(Dizi, 3);
 textBox1.Text = ilk_byte.ToString();
 textBox2.Text = ikinci_byte.ToString();
 textBox3.Text = ucuncu_byte.ToString();
 textBox4.Text = dorduncu_byte.ToString();
 }
 |  
 Dizi değişkenin 
  2. elemanın bir kısmı ilk byte’ta, diğer kısmı 2. byte’ta tutulacağı için bu 
  kod işletildiğinde aşağıdaki gibi bir sonuç alınır. Bit düzeyinde 3. ve 4. byte 
  birleştirildiğinde 10 tabanlı 1000 sayısı elde edilir.
 
 
   
 Herhangi tipteki 
  dizi değişkenin istediğiniz byte’ına istediğiniz değeri yazmak veya mevcut içeriği 
  değiştirmek istiyorsanız Buffer sınıfının SetByte() metodunu kullanabilirsiniz. 
  3 parametreye sahip olan bu metot içeriğinde değişiklik yapılmak istenen dizi 
  değişkeni ilk parametre olarak almaktadır.
 
 Bu metodun nasıl 
  kullanıldığını anlatmak için int tipinde ve 3 elemanlı bir dizi değişken tanımladım 
  ve tanımlama satırında bütün elemanlara 0 aktardım. int tipindeki dizi değişken 
  3 elaman sahip olduğu için bellekte 3*4=12 byte yer kaplar.
 
 int[] Dizi = {0, 0, 0};
 
 Şimdi SetByte() 
  metodu ile int tipindeki bu dizi değişkenin 2. elemanın 1. ve 2. byte’larına, 
  bellekteki sıralamaya göre 5. ve 6. elemanlara 255 sayısını aktaracağım. Sizce 
  bu kod işletildiğinde int tipindeki dizi değişkenin 2. elemanın içeriği ne olur?
 
 
 
   
    | private void 
      Form1_Click(object sender, EventArgs e) {
 int[] Dizi = {0, 0, 0};
 byte Sayi = 255;
 System.Buffer.SetByte(Dizi, 4, Sayi);
 System.Buffer.SetByte(Dizi, 5, Sayi);
 textBox1.Text = Dizi[1].ToString();
 }
 |  Bu kod ile int tipindeki dizi değişkenin 2. elemanın 1. ve 2. byte’larının bütün 
bitlerini 1 ile doldurduğum için 2 tabanlı sayı sisteminde 16 adet 1 bir araya 
getirildiği zaman 65535 sayısı elde edileceği için TextBox’a 65535 yazılır. Şimdi 
bu kodda değişiklik yapıp ayrıca dizi değişkenin 3. byte’ındaki bütün bitlere 
1 ile dolduracağım.
 
 
 
   
    | private void 
      Form1_Click(object sender, EventArgs e) {
 int[] Dizi = {0, 0, 0};
 byte Sayi = 255;
 System.Buffer.SetByte(Dizi, 2, Sayi);
 System.Buffer.SetByte(Dizi, 4, Sayi);
 System.Buffer.SetByte(Dizi, 5, Sayi);
 textBox1.Text = Dizi[0].ToString();
 textBox2.Text = Dizi[1].ToString();
 }
 |  Bu kod işletildiğinde int tipindeki dizi değişkenin bellekteki temsili yerleşimi 
aşağıdaki gibi olur. 2 tabanlı “111111110000000000000000” sayısının 10 tabanlı 
karşılığı 16711680 olduğu için bu kod işletildiğinde ilk TextBox’a 16711680 ve 
2. TextBox ise 65535 yazılır.
 
 
   
                Makale:Buffer Sınıfı ile Tamponlama C#, Visual C# ve .NET Memik Yanık
 |