Serialization(serileştirme), bir nesnenin o anki durumunu(içeriğini) belli bir formata dönüştürüp geçici veya kalıcı bir kaynak üzerinde depolama işlemidir. Bu kaynak bir disk olabildiği gibi hafıza veya network üzerindeki bir akım da olabilir. .NET Framewok’ün birçok sınıfında gizli olarak kullanılan bu işlem daha çok .NET Framework’ün en önemli bileşenlerinden olan Remoting mimarisinde etkilidir. Bu mimaride veriler, serileştirilerek farklı uygulamalar arasında taşınır. Serileştirilmiş veriyi geri elde etme yani orijinal nesne haline çevirme işlemini de deserialization(ters-serileştirme) denilir.
Bir sınıfın serileştirme işlemini desteklemesi için Serializable özniteliğini uygulaması olması gerekir. Ayrıca sınıfı, ISerializable arabiriminden türeterek sınıfının serileştirilmesiyle ilgili daha detaylı ayarlar yapılabilir. DataSet nesnesini WriteXml() metodunu kullanarak güncel içeriğini bir XML belgesine kaydedebiliyor olmamız veya ReadXml() metodu aracılığıyla XML içeriği DataSet içerisine aktarabiliyor olmamızın temelinde DataSet nesnesinin ISerializable ve IXmlSerializable arabirimlerinden türemiş olması yatar.
.NET Framework, 3 tür serileştirme yöntemi sunar:
İkili serileştirme, nesnenin son durumunu bit bit serileştirip bu bilgiyi, diskte bir dosyaya kaydetmek veya .NET Remoting mimarisini kullanarak birbirinden bağımsız uygulamalar arasında taşımak için tercih edilir. Diğer serileştirme yöntemlerinden daha hızlıdır ve daha az bir çıktı üretir. İkili serileştirme işleminden < ı>System.Runtime.Serialization.Formatters.Binary ad alanı altında bulunan BinaryFormatter sınıfı sorumludur. Bu sınıfın, Serialize() metodu kullanılarak nesneler ikili formata dönüştürülür aynı şekilde Deserialize() metodu kullanılarak ikili içerik uygun nesne yapısına dönüştürülür.
Aşağıdaki örnekte basit bir sınıf oluşturulmuş ve bu sınıf tipindeki bir nesnenin ikili formata dönüştürülmesi gösterilmiştir.
[csharp][Serializable] class Musteri { public int MusteriId; public string AdSoyad; public DateTime DogumTarih; } //Serileştirilecek müşteri nesnesini oluşturalım Musteri oM = new Musteri(); oM.MusteriId = 1; oM.AdSoyad = "Ali Çetin"; oM.DogumTarih = new DateTime(1978,02,28); //Serileştirmenin yapılacağı bir akım oluşturalım. //Burada örnek olarak file stream'ı kullanacağız. FileStream oFs = new FileStream(@"C:\Musteri.bin", FileMode.Create); //İkili serileştirme yapacak nesneyi oluşturalım BinaryFormatter oBf = new BinaryFormatter(); oBf.Serialize(oFs, oM);[/csharp] Bu durumda Musteri nesnesi ikili tabanda serileştirilir ve oluşan çıktı C:\Musteri.bin dosyasına yazdılır. Bu dosyadaki içerik ikili formatta olduğu için okunabilir bir yapıda değildir. Bu dosyayı ters serileştirme işleminden geçirip dosyadaki verileri gerçek bir Musteri nesnesine dönüştürelim. Bunun için BinaryFormatter sınıfının Deserialize() metodu kullanılır. [vb]'Serileştirilecek müşteri nesnesini oluşturalım Dim oM As Musteri = Nothing 'Nesneyi kendisinden deserialize edeceğimiz stream'i tanımlayalım Dim oFs As New FileStream("C:\Musteri.bin", FileMode.Open) 'Binary deserialize yapacak nesneyi oluşturalım Dim oBf As New BinaryFormatter() 'Stream içindeki içeriği oM nesnesine deserialize edelim. oM = oBf.Deserialize(oFs) Console.Write(oM.MusteriId & ", " & oM.AdSoyad & ", " & oM.DogumTarih)
//Serileştirilecek müşteri nesnesini oluşturalım Musteri oM = null; //Nesneyi kendisinden deserialize edeceğimiz stream'i tanımlayalım FileStream oFs = new FileStream(@"C:\Musteri.bin", FileMode.Open); //Binary deserialize yapacak nesneyi oluşturalım BinaryFormatter oBf = new BinaryFormatter(); //Stream içindeki içeriği oM nesnesine deserialize edelim. oM = (Musteri)oBf.Deserialize(oFs); Console.Write(oM.MusteriId + ", "+ oM.AdSoyad +", "+ oM.DogumTarih);
1, Ali Çetin, 28.02.1978 00:00:00
İkili serileştirmede sınıf içerisinde serileştirme işlemine dahil edilmesi istenilmeyen üyeler, NonSerialized özniteliğiyle belirtilir.
ADO.NET’in en önemli bileşeni olan DataSet nesnesinin, verileri XML formatında sakladığını biliyoruz. Özellikle farklı konumlardaki uygulamalar arasında yüksek boyutlu DataSet nesnelerinin taşınması veri iletişim süresini uzatabilmektedir. DataSet nesnesi ikili serileştirme işleminden geçirilse bile temelde veriyi yine XML formatında sakladığı için veri boyutunda ciddi bir küçülme olmamaktadır. Bu sorunu aşmak için ADO.NET 2.0 ile birlikte DataSet sınıfına RemotingFormat isimli property eklendi. Bu property, SerializationFormat.Binary veya SerializationFormat.Xml değerlerinden birini alır. Böylece Binary seçeneği seçilerek gerçek anlamdan ikili serileştirme işlemi yapılmış olur.
XML serileştirme, uygulamadaki bir nesnenin güncel durum bilgisini XML formatına dönüştürme amaçlı kullanılır. XML, açık standart bir format olduğu ve işlenmesi kolay olduğu için genellikle farklı uygulamalar arasında veri paylaşımında tercih edilir. Örneğin uygulamadaki bir DataSet nesnesini serileştirip Internet üzerinden başka bir uygulamaya gönderebiliriz. Karşıdaki uygulama aldığı XML içeriği ters serileştirme işleminden geçirip DataSet nesnesinin son durumunu elde etmiş olur. XML serileştirmenin çıktısı, doğası gereği ikili çıktıya göre daha anlaşılır bir formata sahiptir. XML serileştirmenin bazı kısıtlamaları bulunur:
XML tabanlı serileştirmede rol oynayan sınıflar < ı>System.Xml.Serialization kütüphanesi altında bulunur. XML tabanlı serileştirme işleminden sorumlu olan sınıf XmlSerializer sınıfıdır. Bu sınıfın Serialize() metodu, nesnenin güncel içeriğini XML formatına dönüştürür, Deserialize() metodu, Serialize() metodunun ters işlemini gerçekleştirir yani XML verisinden uygun nesneyi oluşturur. Bu sınıfın diğer önemli üyesi olan CanDeserialize() metodu, XML verisinin ters serileştirme işlemi için uygun olup olmadığını denetler.
XML serileştirme işleminde, serileştirilecek nesnenin tipi, XmlSerializer sınıfının yapıcı metoduna parametre olarak geçilir.
'Serileştirilecek müşteri nesnesini oluşturalım Dim oM As New Musteri() oM.MusteriId = 1 oM.AdSoyad = "Ali Çetin" oM.DogumTarih = New DateTime(1978, 2, 28) 'Serileştirmenin yapılacağı bir akım oluşturalım. 'Burada örnek olarak file stream'ı kullanacağız. Dim oFs As New FileStream("C:\Musteri.xml", FileMode.Create) 'XML serileştirme yapacak nesneyi oluşturalım 'XmlSerializer'ın yapıcı metoduna Musteri sınıfının tipi gönderilir Dim oXs As New XmlSerializer(GetType(Musteri)) oXs.Serialize(oFs, oM)
//Serileştirilecek müşteri nesnesini oluşturalım Musteri oM = new Musteri(); oM.MusteriId = 1; oM.AdSoyad = "Ali Çetin"; oM.DogumTarih = new DateTime(1978, 02, 28); //Serileştirmenin yapılacağı bir akım oluşturalım. //Burada örnek olarak file stream'ı kullanacağız. FileStream oFs = new FileStream(@"C:\Musteri.xml", FileMode.Create); //XML serileştirme yapacak nesneyi oluşturalım //XmlSerializer'ın yapıcı metoduna Musteri sınıfının tipi gönderilir XmlSerializer oXs = new XmlSerializer(typeof(Musteri)); oXs.Serialize(oFs, oM);
Bu işlemden sonra Musteri nesnesinin o anki durumu XML formatında diske yazılır.
Görüldüğü gibi belge içerisinde alanların veri tipleriyle ilgili tanımlama bulumamaktadır.
Şimdi bu belgedeki verileri sözkonusu Musteri sınıfına uygun bir nesneye geri yükleme yapalım.
'Yeni bir Musteri nesnesi oluşturalım Dim oM As Musteri = Nothing 'Deserialization işleminde kullanılacak serializer nesnesi Dim oXs As New XmlSerializer(GetType(Musteri)) Dim oXr As XmlReader = New XmlTextReader("C:\Musteri.xml") 'XML verisinin Deserialize durumunu denetleyelim If oXs.CanDeserialize(oXr) Then 'XML verisini deserialize edelim oM = oXs.Deserialize(oXr) Console.Write(oM.MusteriId & ", " & oM.AdSoyad & ", " & oM.DogumTarih) End If
//Yeni bir Musteri nesnesi oluşturalım Musteri oM = null; //Deserialization işleminde kullanılacak serializer nesnesi XmlSerializer oXs = new XmlSerializer(typeof(Musteri)); XmlReader oXr = new XmlTextReader(@"C:\Musteri.xml"); //XML verisinin Deserialize durumunu denetleyelim if (oXs.CanDeserialize(oXr)) { // XML verisini deserialize edelim oM = (Musteri)oXs.Deserialize(oXr); Console.Write(oM.MusteriId + ", " + oM.AdSoyad + ", " + oM.DogumTarih); }
1, Ali Çetin, 28.02.1978 00:00:00
< ı>System.Xml.Serialization ad alanı, XML formatında serileştirilecek nesneyle ilgili detaylı ayarlama yapmak için çeşitli öznitelikler içerir. Örneğin nesneye ait bir özelliği, XML belgesinde öznitelik olarak tanımlamak için XmlAttribute niteliği, serileştirme işlemine dahil edilmeyecek alanlar için XmlIgnore niteliği, alanın XML belgesindeki elemen yapısını düzenlemek için XmlElement niteliği kullanılır. Musteri sınıfını aşağıdaki gibi düzenleyelim.
Public Class Musteri [csharp]public class Musteri { [XmlAttribute("MusteriKodu")] public int MusteriId; [XmlElement("MusteriAdiSoyadi")] public string AdSoyad; [XmlIgnore] public DateTime DogumTarih; }[/csharp] Bu durumda örnekte kullandığımız nesnenin XML çıktısı şu şekilde olacaktır. [xml] <u><b>SOAP serileştirme,</b></u> XML serileştirme işleminin bir türü olup SOAP formatında serileştirme yapmak için kullanılır. Basit nesne erişim prokolü olarak tanımlanan SOAP(Simple Object Access Protocol), uygulamalar arasında HTTP üzerinden veri iletimini sağlamak amacıyla geliştirilmiş XML tabanlı bir iletişim protokolüdür. Bu protokol, dağıtık uygulamalarda ve web servislerinin haberleşmesinde kullanılılır. .NET Framework'te nasıl ki ikili serileştirme, BinaryFormatter isimli formatter nesnesi tarafından gerçekleştiriliyorsa SOAP serileştirme de SoapFormatter isimli formatter nesnesi tarafından gerçekleştirilir. SoapFormatter sınıfı, < ı>System.Runtime.Serialization.Formatters.Soap.dll kütüphanesi altında bulunmaktadır. SOAP serileştirme için projemize bu kütüphaneyi referans olarak eklemeyi unutmamalıyız. SoapFormatter sınıfının da serileştirme işlemini yapan <b>Serialize()</b> ve ters serileştirme işlemini yapan <b>Deserialize()</b> metodu bulunur. [vb] [csharp][Serializable] public class Musteri { public int MusteriId; public string AdSoyad; public DateTime DogumTarih; } //Serileştirilecek müşteri nesnesini oluşturalım Musteri oM = new Musteri(); oM.MusteriId = 1; oM.AdSoyad = "Ali Çetin"; oM.DogumTarih = new DateTime(1978, 02, 28); //Serileştirmenin yapılacağı bir akım oluşturalım. FileStream oFs = new FileStream(@"C:\Musteri.xml", FileMode.Create); SoapFormatter oSf = new SoapFormatter(); oSf.Serialize(oFs, oM);[/csharp] Bu şekilde serileştirilmiş nesne, aşağıdaki içeriğe dönüştürülür. [xml] Serileştirilmiş SOAP formatındaki bu veriyi uygulamadaki Musteri nesnesine dönüştürelim. [vb]Dim oM As Musteri = Nothing Dim oFs As New FileStream("C:\Musteri.xml", FileMode.Open) Dim oSf As New SoapFormatter() 'SOAP verisini deserialize edelim oM = oSf.Deserialize(oFs) Console.Write(oM.MusteriId & ", " & oM.AdSoyad & ", " & oM.DogumTarih)
Musteri oM = null; FileStream oFs = new FileStream(@"C:\Musteri.xml", FileMode.Open); SoapFormatter oSf = new SoapFormatter(); // SOAP verisini deserialize edelim oM = (Musteri)oSf.Deserialize(oFs); Console.Write(oM.MusteriId + ", " + oM.AdSoyad + ", " + oM.DogumTarih);
1, Ali Çetin, 28.02.1978 00:00:00
Serileştirmeyle ilgili olarak yine bizim tarafımızdan yazılmış başka bir nesneyle ilişkili bir nesneyi kullanalım. Musteri sınıfına AdresBilgi isimli başka bir sınıfın türünden olan Adres isimli bir property ekleyelim.
[csharp][Serializable] public class Musteri { public int MusteriId; public string AdSoyad; public DateTime DogumTarih; public AdresBilgi Adres; } [Serializable] public class AdresBilgi { public string CaddeSokak; public string Sehir; } //Adres nesnesi AdresBilgi oAdres = new AdresBilgi(); oAdres.CaddeSokak = "A Cd. B Sokak"; oAdres.Sehir = "İstanbul"; //Musteri nesnesi Musteri oM = new Musteri(); oM.MusteriId = 1; oM.AdSoyad = "Ali Çetin"; oM.DogumTarih = new DateTime(1978, 02, 28); oM.Adres = oAdres;[/csharp] Bu verilere göre XML ve SOAP serileştirme işleminde bulunalım. [vb]'Akım nesnesi Dim oFs As New FileStream("C:\Musteri.xml", FileMode.Create) Dim oXs As New XmlSerializer(GetType(Musteri)) oXs.Serialize(oFs, oM)
//Akım nesnesi FileStream oFs = new FileStream(@"C:\Musteri.xml", FileMode.Create); XmlSerializer oXs = new XmlSerializer(typeof(Musteri)); oXs.Serialize(oFs, oM);
Adres düğümü, Musteri düğümünün bir alt elementi olarak tanımlanmıştır. SOAP tabanlı serileştirmeye bakalım.
'Akım nesnesi Dim oFs As New FileStream("C:\Musteri.xml", FileMode.Create) Dim oSf As New SoapFormatter() oSf.Serialize(oFs, oM)
//Akım nesnesi FileStream oFs = new FileStream(@"C:\Musteri.xml", FileMode.Create); SoapFormatter oSf = new SoapFormatter(); oSf.Serialize(oFs, oM);
Sonuçta grüldüğü gibi Adres alanı için ayrı bir veri tipi tanımlaması yapılmış ve Adres alanından o veri tipine referans verilmiştir.
elinize sağlık çok güzel anlatmışsınız
müthiş olmuş.
Cok super bir anlatim olmus, her ne kadar oturup kodlamaya baslamadan iyice ogrenilemeyecegi icin, genel olarak anlamak icin cok guzel. Remoting uygulamalari gelistiriyorsaniz mutlaka ogrenilmasi gereken bir konu. Kitaplarinizi da ayrica siparis ettim, dort gozle bekliyorum derinlemesine ogrenebilmek icin.
çok sağolun. emekleriniz duara vesile oluyor.
Harika bir anlatım, teşekkürler.