İ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.
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.
[Serializable]
public class BinarySerial
{
public int sayi1;
public string strName;
}
//aşağıda bu nesnenin bir örneği yaratılmakta ve myFile.bin
dosyasına serileştirilmektedir.
BinarySerial nesneOrnegi = new BinarySerial();
nesneOrnegi.sayi1 = 15;
nesneOrnegi.strName = “Hakan”;
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;
Console.WriteLine(“{0}”,nesnem.sayi1);
Console.WriteLine(“{0}”,nesnem.strName);
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
[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