Bu site emekli olmuştur. Arşiv amaçlı olarak BT AKADEMİ sponsorluğunda yayın hayatına devam etmektedir.




C#nedir?com
 
YAZAR HAKKINDA
Memik Yanık
Memik Yanık
http://www.csharpnedir.com/
İletişme geçmek için tıklayın.
3 Makalesi yayınlanmakta.
Yazar hakkında detaylı bilgi için tıklayın.
Yayınlanan diğer makaleleri için tıklayın.
İlgili etiketler: bellekte blockcopy() degiskenin dizinin elemani elemanin eventargs kaynak metodu parametre sender sinifinin tabanli tipindeki verilen C# / VC#/.NET Memik Yanık
 
YAZI HAKKINDA
Türü : Makale
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
Seviyesi : Başlangıç
Kategori : C# / VC#/.NET
Yayınlanma Tarihi : 6.1.2007
Okunma Sayısı : 30001
Yorum Sayısı : 0     yorum yaz
Site İçi AramaSİTE İÇİ ARAMA
Üye Girişini AçÜye GİRİŞİ
Üye girişi için tıklayın.
Kullanıcı Adı
Şifre
 
Beni her zaman hatırla
Bir hafta boyunca kullanıcı bilgilerinizi kullanıcı çıkışı yapana kadar hatırlar. (Paylaşılan bilgisayarlarda önerilmez.)
 
Şifremi / Kullanıcı Adımı unuttum.
 
.net TV RSS Serbest KÖŞE (?)
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
emre TAŞ
Silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
Makale Gönder Bende Yazmak İstiyorum
.net TV RSSBlogroll
Turhal Temizer
Conda install environment.yml Package 23.11.2024
Turhal Temizer
Mac OS/X Removing CUDA 23.11.2024
Burak Selim Şenyurt
Rust ile ECS Yaklaşımını Anlamak 23.11.2024
Burak Selim Şenyurt
Birlikte Rust Öğrenelim Serisi 23.11.2024
  Diğer Herşey
Sponsorlar
BT Akademi
Medya Portakal
Video Hosting Sponsoru
Csharpnedir.com bir Ineta üyesidir
Uzman Abi
Her Yönüyle C# - Sefer Algan
Buffer Sınıfı ile Tamponlama
 
Kapat
Sayfayı Yazdır Sık Kullanılanlara Ekle Arkadaşıma Gönder MySpace Del.Ico.Us Digg Facebook Google Mixx Reddit StumbleUpon
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.


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();
}
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.


Çü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?

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 ş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.


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.


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 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.

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.


short[] Kaynak_Dizi = {1000,2000};
byte[] Hedef_Dizi = new byte[10];
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.



Ş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.

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();
}
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.



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.


private void Form1_Click(object sender, EventArgs e)
{
    int[] Dizi = new int[10];
    int sayi = System.Buffer.ByteLength(Dizi);
    textBox1.Text = sayi.ToString();
}
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)
{
    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();
}
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.

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
  • Yazılan Yorumlar
  • Yorum Yaz
Bu konu hakkında yayınlanan yorum bulunmamaktadır.
"Yorum Yaz" tabını kullanarak sizde yorumlarınızı yazabilirsiniz.
Yorum yazabilmek için üye girişi yapmalısınız. Üye girişi için tıklayın.
Üye değilseniz Üyel Ol linkine tıklayarak üyeliğinizi hemen başlatabilirisniz.
 
  • Bu Konuda Son 10
  • Eklenen Son 10
  • Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor