Rehber Buffer nedir ve nasıl kullanılır?

Merhaba 😇

Bugün sizlere Buffer'ın ne olduğu ve nasıl kullanıldığını anlatmaya çalışacağım.

Makalemzi 2 ana maddeden oluşuyor;
  • Buffer nedir?
  • Buffer nasıl kullanılır?
Buffer nedir?

Buffer (tampon bellek)
, verilerin I/O işlemlerinden sonra belleğe yazılmadan önce uğradıkları bir sahadır. Bufferlar I/O işlemi sırasında kullanıcının beklemesini engellemek için kullanılırlar. Bellekten okumak ve belleğe yazmak uğraştırıcı bir işlemdir. Sistemi yorar ve hız olarak yavaştır. I/O aygıtlarından gelen veriler bu sebeple önce bir havuzda toplanır.

Böylece bu havuz belirli miktarlarda dolduktan sonra toplu olarak belleğe yazılır. Bu sisteme performans kazandıran bir harekettir. İkinci bir unsur ise tampon belleğin olmadığını düşündüğümüz zaman verilerin yazıldığı veya okunduğu anlarda sistem bununla meşgul olacağı için yeni veri girişi okunması yapılamayacaktır. Bu da kullanıcının beklemesine sebep olacaktır. Buffer bu derdin de dermanı olmuştur çünkü veri yazımı sırasında tampon bellek yeni veriler almaya devam edebilecektir.

Yani havuza benzetirsek, havuz tabanındaki büyük bir giderden su boşaltılırken, yukarıdaki bir musluk da havuzu doldurmaya devam edebilmektedir. Bu sayede kullanıcı bekelemez, işlemler daha kolay ve düşük gereksinim ile olur.

Son olarak, Buffer kullanırken çok yüksek boyutlu bir işlem dahi yapsanız RAM kullanımı minimum olarak devam eder. Çünkü buffer belleğe belli paketler ve aralıklarla yazar.

Yukarıdaki yazının bir kısmını kendim yazmak yerine bu kaynaktan aldım:

Şimdi ise Buffer kullanmayı bir örnek ile gösterelim.

Bu örnekte bir dosyayı okuyup SHA-256 değerini alacağız. Ancak bunu Buffer kullanarak yapacağız.

Böyle bir Form tasarladım.

  • BackgroundWorker.
  • ProgressBar.
  • 2 adet Label.
  • 2 adet Button.
1679322048247.png


BackgroundWorker'ın WorkerReportsProgress özelliği açık olmalı.

1679322080505.png


BackgroundWorker hakkında detaylı bilgi için rehberime bakabilirsiniz;

BackgroundWorker DoWork işlemi kodları;

C#:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e){

    string file_path = e.Argument.ToString();

    byte[] buffer;
    int bytes_read;
    long size;
    long total_bytes_read = 0;

    using (Stream file = File.OpenRead(file_path)){

        size = file.Length;

        using (HashAlgorithm hasher = SHA256.Create()){
            do{
                buffer = new byte[8192]; // 8KB aralıklarla belleğe toplu olarak yazacak

                bytes_read = file.Read(buffer, 0, buffer.Length);
                total_bytes_read += bytes_read;
                hasher.TransformBlock(buffer, 0, bytes_read, null, 0);
                backgroundWorker1.ReportProgress((int)((double)total_bytes_read / size * 100));

            }while (bytes_read != 0);

                hasher.TransformFinalBlock(buffer, 0, 0);
                e.Result = HashStringRotate(hasher.Hash);
        }
    }
}

Oluşturulan Byte değerini okuyabilmek için String'e dönüştürüyoruz.

C#:
private static string HashStringRotate(byte[] hash_bytes){
    StringBuilder hash = new StringBuilder(32);
    foreach (byte be in hash_bytes){
        hash.Append(be.ToString("X2").ToUpper());
    }
    return hash.ToString();
}

ProgressBar ve Label'de gösterebilmek için BackgroundWorker ProgressChanged işlemi kodları;

C#:
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e){
    progressBar1.Value = e.ProgressPercentage;
    ProgressPercentLabel.Text = "%" + e.ProgressPercentage;
}

İşlem bittiğinde Label'e Hash değerini yazdırmak için BackgroundWorker RunWorkerCompleted işlemi kodları;

C#:
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){
    HashLastLabel.Text = e.Result.ToString();
}

Butona basıldığında dosya seçme Dialog'u çıkması için gerekli kodlar;

C#:
private void FileSelectBtn_Click(object sender, EventArgs e){
    OpenFileDialog ofd = new OpenFileDialog{
        InitialDirectory = @"C:\Users" + Environment.UserName + @"\Desktop\",
        Title = "Dosya seçiniz",
        Filter = "Tüm Dosyalar (*.*)|*.*",
     };

     if (ofd.ShowDialog() == DialogResult.OK){
         FileSelectTextBox.Text = ofd.FileName;
     }
}

İşlemleri başlatmak için gerekli Button kodu.

C#:
private void StartHashBtn_Click(object sender, EventArgs e){
    if (FileSelectTextBox.Text != ""){
        backgroundWorker1.RunWorkerAsync(FileSelectTextBox.Text.Trim());
    }
}

Şimdi başlatalım;

1679322489490.png


1679322498831.png


Gördüğünüz üzere, işlem devam ederken ram kullanımı artmıyor. Çünkü buffer kullandık :)

1679322504715.png


İşlem tamamlandı.

1679322510211.png


Evet, gördüğünüz üzere Buffer böyle kullanılıyor. En düşük bellek gereksinimi ile istediğiniz işlemi yapabilirsiniz.

Umarım açıklayıcı bir şekilde anlatmışımdır.

Okuduğunuz için teşekkür ederim.

Yazılım rehberlerimin devamı gelecek.

İyi çalışmalar, kolay gelsin 😎

İşine yarayacağını düşündüğüm kişiler;
@Enes3078 @Mithat Berhan @246941 @Beroski @Bora Dere @Vavien.
 
Küçük bir örnek atabilirim size. İngilizce bir örnek. BackgroundWorker ile nasıl dosya yüklendiğini ve dinamik olarak % kaç olduğunu gösteriyor.

 

Technopat Haberler

Yeni konular

Geri
Yukarı