Kayıt
4 Ekim 2007
Mesajlar
2.262
Beğeniler
3
Şehir
Lise
Serileştirme nedir?

Serialization (yazının bundan sonraki bölümlerinde “serileştirme” adı ile anılacaktır); bir nesnenin saklanacak / transfer edilecek forma dönüştürülmesi işlemidir.

Serileştirmenin tersi olarak adlandırılan Deserialization ise, bir akışın (Stream) nesne modeline dönüştürülmesi işlemi olarak adlandırılır.

.NET Framework içerisinde buluan System.Runtime.Serialization isim uzayından erişebileceğimiz serileştirme sınıfları ve araçları sayesinde, kendi nesnelerimizi istediğimiz formatta saklayabiliriz.

.NET Framework, bize serileştirme için iki metod sunar;

* XML ve SOAP Serileştirme (XML and SOAP Serialization)
* İkili Serileştirme (Binary Serialization)

İkili serileştirme, tür bağımlılığı açısından önemlidir. İkili serileştirme işlemi daha çok birbirinden bağımsız iki uygulama arasında nesne modellerini taşımak için kullanılır.

Bu metod ile örneğin; bir nesne modelini diskinizdeki bir dosyaya, yada networkteki başka bir bilgisayara hatta .NET remoting kullanarak farklı bir domain içerisinde bulunan bir bilgisayardaki uygulamalara bile taşıyabilirsiniz.

XML ve SOAP serileştirme ise, tür esnekliği ile ön plana çıkmaktadır. XML serileştirme işleminde sadece ortak özellik ve metodlar serileştirilebilir. Bu modelde verinizi, kullanacak olan uygulamayı kısıtlamadan saklayabilirsiniz. XML ve SOAP açık bir standart olduğundan ve her türlü uygulama tarafından rahatlıkla okunabildiğinden veri paylaşımı oldukça hızlı sağlanabilmektedir.



Binary ve XML serileştirme

İkili (Binary) Serileştirme:


İkili serileştirme işlemi; bir nesnenin durumunun saklama ortamına uygun hale getirilip yazılması süreci olarak tanımlanabilir. İşlem süresince, nesnenin “public” ve “private” öğeleri, sınıfın adı, sınıfı barındıran Assembly’ nin adı saklama ortamına yazılmak üzere “byte” lar akışına çevirilir.

Nesne, Deserialize edildiğinde ise nesnenin tam bir kopyası oluşturulur ve kullanıma sunulur.

XML ve SOAP serileştirme (eXtensible Markup Language & Simple Object Access Protocol)

Xml serileştirme, veri türünü dikkate almaksızın bir nesnenin tüm ortak metodlarını, özelliklerini ve değişkenlerini serileştirir. XML serileştirme ile her uygulamada kullanılabilen nitelikte sınıf örnekleri yaratılabilir.

XML serileştirmenin yıldızının parladığı noktalar ise, klasik Windows uygulamaları ile İnternet uygulamaları arasında iletişim gerektiği durumlar olarak bilinmektedir.

Bir Windows uygulamasında kullandığınız sınıf örneğini, bir Web servisi aracılığı ile Web uygulamanıza taşımanıza olanak sağlayan yegane yöntem XML serileştirmedir.

Aşağıdaki örneği incelediğinizde, XML serileştirme işlemi ile serileştirilen bir nesne modelinin nasıl bir hal alacağını görebilirsiniz.

public class Musteri
{
public string musteriAdi;
}

Yukarıdaki sınıfın bir örneği serileştirildiğinde ise, aşağıdaki hali alacaktır;

<Musteri>
<musteriAdi>Kemal Kartalayak</musteriAdi>
</Musteri>

Gördüğünüz gibi, yukarıdaki formata sahip herhangi bir datayı istediğini bir uygulamada kullanmak sizin elinizde. Tür bağımsızlığı bu gibi durumlarda kendisini göstermektedir.

Yine bir örnekle açıklamak gerekirse; Asıl veritabanı yerel bilgisayarınızda bulunan bir müşteri listesini güncel olarak web sitenizde yayınlamanız gerekmekte. Ancak bu ortam hem web sitesinden erişilebilir olmalı, hem de yerel makinenızdaki bir program tarafından okunabilmeli. İşte bu durumda veritabanı içerisindeki verileri XML ile serileştirmeniz hem Web uygulamanız tarafından okunmasını sağlayacaktır, hem de istediğiniz Windows uygulaması tarafından görüntülenebilecektir.




Binary serileştirme hakkında

Binary Serileştirme uygulaması:



Serileştirme üzerine bu ilk makalemizde, ikili serileştirme uygulamasına yer verelim ve daha sonrakilerde de XML serileştirmeyi derinlemesine inceleyelim.

İkili serileştirme işlemi en basit yöntem ile nesneye Serializable etiketi verilerek yapılır. Aşağıdaki örneğimizde basit bir sınıf serileştirilmekte ve bir dosyaya yazılmaktadır.

Kod:
[Serializable]
public class BinarySerial
{
Kod:
            public int sayi1;
            public string strName;
}

//aşağıda bu nesnenin bir örneği yaratılmakta ve myFile.bin dosyasına serileştirilmektedir.

Kod:
BinarySerial nesneOrnegi = new BinarySerial();
nesneOrnegi.sayi1 = 15;
nesneOrnegi.strName = “Hakan”;
Kod:
IFormatter bicimlendirici = new BinaryFormatter();
Stream akis = new FileStream(“myFile.bin”,FileMode.Create,FileAccess.Write);
bicimlendirici.Serialize(akis,nesneOrnegi);
akis.Close();

Nesnemizin dosyadan tekrar alinmasi ise “Deserialization” işlemi ile yapılır;
IFormatter bicimlendir = new BinaryFormatter();
Stream akis = new FileStream(“myFile.bin”,FileMode.Open,FileAccess.Read);
BinarySerial nesnem = (BinarySerial) bicimlendir.Deserialize(akis);
akis.Close();


//aşağıdaki şekilde nesnemizin değerlerini test edebilirsiniz;
Kod:
Console.WriteLine(“{0}”,nesnem.sayi1);
Console.WriteLine(“{0}”,nesnem.strName);


Uygulama

Kendi verinizi kendiniz saklayın:


Binary serileştirme ile ilgili son örneğimiz, tıpkı bir veritabanı kullanır gibi kendi verimizi saklayıp daha sonra istediğimiz zaman erişebileceğimiz bir uygulama.

Uygulamamızda, Storage sınıfı saklayacağımız veriyi biçimlendirmek için kullanacağımız sınıf olmakla beraber bu örnekte içerisinde sadece temel metodları barındırmaktadır.

Veri saklamak için klasik Hashtable yapısını kullanacağız. C# için bir konsol uygulaması başlatıyoruz ve yeni bir sınıf ekleyip adını “Storage.cs” olarak ayarlıyoruz.

Storage.cs:


//istedigimiz program datasini kaydetmek icin, serializable bir class yaratiyoruz

Kod:
 [Serializable]
 public class Storage
 {
      private Hashtable storageData; //ikili tablo olarak saklayacagimiz verileri tutacak
      public Storage()
            {

                 //constructor metodumuz, deseriazlize edildigi zaman
                 //cagirilmayacagi icin, icerisine onemli islemleri yazmiyoruz.

                 storageData = new Hashtable();
            }

           //yeni bir datayi saklamak istedigimizde, kullanacagimiz metod.

           public void AddData(object data, string identifier)
                 {
                         if(!isExists(data) || !isExists(identifier))
                               {
                                    storageData.Add((object) identifier,data);
                               }
                  }

           //herhangi bir data silmek istedigimizde, bu metod yardimimiza kosuyor.

           public void RemoveData(string identifier)
                 {
                         if(isExists(identifier))
                               {
                                     storageData.Remove((object) identifier);
                               }
                  }

           //hashtable icerisindeki bir verinin, key ini aramak icin

           public string GetIdentifier(object data)
                  {
                         if(isExists(data))
                               {
                                       foreach(string strKey in storageData.Keys)
                                             {
                                                   if(storageData[strKey] == data)
                                                           {
                                                                return strKey;
                                                            }
                                              }

                                       return null;
                                }
                           return null;
                    }

           //storageData hashtableimizi dondurecek property.

           public Hashtable storage
                {
                     get
                        {
                                 return this.storageData;
                        }

                }

            #region Herhangi bir verinin HashTable icerisinde olup olmadigini degerlendir
           private bool isExists(object dataToSearch)

               {
                    if(storageData != null)
                              {
                                  if(storageData.ContainsValue(dataToSearch))
                                           {
                                                  return true;
                                            }
                              }
                    return false;
               }

             private bool isExists(string idToSearch)

                  {
                         if(storageData != null)
                                {
                                     if(storageData.ContainsKey((string) idToSearch))
                                               {
                                                     return true;
                                                }
                                }

                          return false;
                   }

             #endregion

Storage sınıfımız hazır olduğuna göre artık bu sınıfı kullanarak saklanan veriyi serileştiren uygulamamızı yazabiliriz.

 

class Class1

 {

 //storage nesnemizin ornegini olusturuyoruz.

 private static Storage sakla;

 //ikili (binary) serilestirme icin interface ornegini tanimliyoruz.

 private static IFormatter IBinaryBicimle;

 //serilestirilmis datayi hangi dosyada saklayacagimiz.

 private static string storageFileName = "myDatabase.bin";

 //dosyaya yazmak icin kullanacagimiz strem

 private static Stream isle;

 [STAThread]

 static void Main(string[] args)

 {

 Console.WriteLine("Serilestirme ornek projesi, by scriptMan");

 //storage nesnemize saklanacak verileri yaziyoruz

 sakla = new Storage();

 for(int i=0; i<50; i++)

 {

 sakla.AddData(i,"saklanan"+i);

 }

 Console.WriteLine("Serilestirme islemine baslamak icin bir tusa basin");

 Console.ReadLine();

 DoSerialize(); //serilestir

 Console.WriteLine("Serilestirme tamamlandi, Serilestirilen veriyi okumak icin bir tusa basiniz");

 Console.ReadLine();

 PurgeData(); //deserialize et, ve ekrana yaz.

 Console.ReadLine();

 }

 private static void PurgeData()

 {

 //serilestirilmis nesneyi geri cagirip, datayi ekrana basalim

 IBinaryBicimle = new BinaryFormatter();

 isle = new FileStream(storageFileName,FileMode.Open,FileAccess.Read);

 sakla = (Storage) IBinaryBicimle.Deserialize(isle);

 isle.Close();

 System.Collections.Hashtable serializedHashTable = sakla.storage;

 foreach(string strData in serializedHashTable.Keys)

 {

 Console.WriteLine("Key: {0} Data: {1}",strData,serializedHashTable[strData]);

 }

 }

 private static void DoSerialize()

 {

 //binaryformatter nesnesinin bir ornegini aliyoruz..

 IBinaryBicimle = new BinaryFormatter();

 //filestream kullanarak, olusturacagimiz dosyayi belirliyoruz..

 isle = new FileStream(storageFileName,FileMode.Create,FileAccess.Write);

 //serilestirme icin yapmamiz gereke tek sey, binaryformatter nesnemizin..

 //serialize metodunu cagirmak ;)

 IBinaryBicimle.Serialize(isle,sakla);

 isle.Close();

 //program icerisinde olusturdugumuz hashtable' in icini temizliyoruz..

 //bolece serilestirilmis nesne tekrar okundugunda, otomatik doldugunu..

 //gorebilecegiz.

 System.Collections.Hashtable htClear = sakla.storage;

 htClear.Clear();

 }

 }

Uygulamamızı çalıştırmadan önce, dahil etmemiz gereken isim uzaylarını da yazmakta fayda görüyorum.

 

Class1 için;

 

System.Runtime.Serialization

System.Runtime.Serialization.Formatters.Binary

System.IO

 

Storage sınıfı için:

System.Collections
 
Yukarı Alt