Wednesday, 23 July 2014

Serializatsiya C#

SERIALIZATION AND DE - SERIALIZATION IN C#


Serializatsiya deganda  ob'yektni baytli streamga o’girish tushiniladi. Asosiy ahamiyati ob’ekt holatini saqlash va kerak bo’lganda uni tiklashdan iborat. Serializatsiya qilingan o’byekt haqidagi ma’lumotlar streamda saqlanadi, bunda faqat o’byekt qiymatlarigina emas ob’yekt tipi, uning versiyasi, nomi haqidagi ma’lumotlar ham saqlanadi. Hosil qilingan stream(oqim) yordamida ob’yekt haqidagi ma’lumotlarni ma’lumotlar bazasida, ixtiyoriy faylda (ikkilik (binnary), xml, yoki  boshqa ko’rinishda (CUSTOM)) yoki vaqtincha xotirada(InMemory) saqlash mumkin. 

Serializatsiya yordamida ob'yekt holatini saqlab borish, lozim bo’lganda turli ob’yektlar bilan ma’lumot almashinish, web – servislar orqali boshqa applicationga ob’ektni yuborish, ob’ektni XML  satr ko’rinishda bir domendan boshqasiga yuborish mumkin.
Ob’ektni serializatsiya qilish uchun o’byekt, ob’yekt serializatsiya qilinishi uchun stream va Formatter lozim bo’ladi. C# da System.Runtime.Serialization – ob’ektni serializatsiya va deserializatsiya qilish uchun ishlatiladigan classlardan tashkil topgan. “using” bo’limiga System.Runtime.Serialization ni qo’shib qo’yish lozim. Ob’ektdagi atributlar serializatsiya bo’lishi uchun SerializableAttribute tipida bo’lishi mumkin, bu tipda bo’lmagan atributlarni serializatsiya qilishda yuzaga keladigan xatoliklarni SerializationException yordamida qayta ishlash mumkin. Agar ob’yet sinfi ichidagi bironta maydonning serializatsiya bo’lmasligini xoxlasangiz unga NonSerializedAttribute atributini qo’llash mumkin.
Serializatsiyada ikkilik(binnary, byte) yoki XML serializatsiyalardan foydalanish mumkin. Ikkilik serializatsiyada ob’yekt tushinarsiz mashina kodiga o’girilgan holatga o’tkaziladi, XML serializatsiyada esa ob’yekt XML ko’rinishda serializatsiyalandi va uni boshqa applicationda to’g’ridan to’g’ri foydalanish mumkin bo’ladi. Ikkilik ko’rinishdagi serializatsiya ko’p holatda socket orqali ishlaganda ishlatiladi.
Endi serializatsiya ve deserializatsiyani quyidagi “Telefonlar kitobi (Phone book)”dasturi misolida ko’rib chiqamiz:
C# DTning Consule Application tipidagi yangi Project yaratamiz, va unda TelNumberType enum, TelNumber sinf, Contact sinf, PhoneBook sinfini quyidagi tartibda yaratamiz:

TelNumberType:

    internal enum TelNumberType
    {
        UyNomeri,
        IshNomeri,
        FaxNomeri
    }

TelNumber:

    [Serializable()]
    internal class TelNumber
    {
        public int Id { get; set; }
        public TelNumberType Type { get; set; }
        public string Number { get; set; }
    }

    
   Contact:

[Serializable()]
     internal class Contact
     {
        public Guid id { get; set; }
        public string Name { get; set; }
        public List<TelNumber> telNumbers { get; set; }

        public Contact()
        {
            telNumbers = new List<TelNumber>();
        }
     }

PhoneBook:

   [Serializable()]
       internal class PhoneBook
       {
   
          public string Name { get; set; }
          public List<Contact> Contacts { get; set; }

          public PhoneBook()
           {
               this.Contacts = new List<Contact>();
           }
        }

[Serializable()] - atributi sinf ob'eytining serializatsiya qilinishini bildiradi.

Ob'ektni Serializatsiya de Deserializatsiya qilish uchun SerializeObject va DeserializeObject metodlarini quyidagi ko'rinishda yaratamiz:

SerializeObject:

        private static string SerializeObject(object obj)
        {
            if (!obj.GetType().IsSerializable)
            {
                return null; //Agar ob'ekt sinfi yuqorisiga                                          //[Serializable()] atributi qo'yilmagan
                             //bo'lsa hech qanday serializatsiya                                      //bajarilmaydi
            }

            using (MemoryStream stream = new MemoryStream())
            {
                new BinaryFormatter().Serialize(stream, obj);
                return Convert.ToBase64String(stream.ToArray());
            }
        }

DeserializeObject:

              private static object DeserializeObject(string str)
        {
            byte[] bytes = Convert.FromBase64String(str);

            using (MemoryStream stream = new MemoryStream(bytes))
            {
                return new BinaryFormatter().Deserialize(stream);
            }
         }

Ushbu yaratilgan sinflar va metodlardan foydalanib serializatsiya va deserializatsiyani "Program" sinfidagi "main" metodi ichida tekshirib ko'rishimiz mumkin.

                     Dasturning umumiy ko'rinishi quyidagicha bo'ladi:

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace ConsoleApplicationSerializationTest1
{
    internal class Program
    {
        private static string SerializeObject(object obj)
        {
            if (!obj.GetType().IsSerializable)
            {
                return null; //Agar ob'ekt sinfi yuqorisiga [Serializable()] atributi                                      //qo'yilmagan bo'lsa hech qanday serializatsiya bajarilmaydi
            }

            using (MemoryStream stream = new MemoryStream())
            {
                new BinaryFormatter().Serialize(stream, obj);
                return Convert.ToBase64String(stream.ToArray());
            }
        }

        private static object DeserializeObject(string str)
        {
            byte[] bytes = Convert.FromBase64String(str);

            using (MemoryStream stream = new MemoryStream(bytes))
            {
                return new BinaryFormatter().Deserialize(stream);
            }
        }

        private static PhoneBook pb;
        private static void Main(string[] args)
        {
            pb = new PhoneBook();
            pb.Name = "MyPhoneBook";
            Console.WriteLine("Serializatsiya va Deserializatsiya - PhoneBOOK misolida:");
            Console.WriteLine("--------------------------------------------------------");
            string inputString=String.Empty;
            Contact myContact;
            int contactsCount = 0;
            while (true) //Foydalanuvchi "." ni kiritguncha ob'ektga qiymat kiritishda davom                          //etishi mumkin
            {
                contactsCount++;
                Console.Write(">{0}-Kontakt nomi(yoki kiritishni yakunlash uchun '.' ni kiriting):",contactsCount);
                inputString = Console.ReadLine();
                if (inputString.Equals(".")) break;
                myContact = new Contact();
                myContact.id = Guid.NewGuid();
                myContact.Name = inputString;
                Console.Write(">Uy tel. nomeri:");
                inputString = Console.ReadLine();
                myContact.telNumbers.Add(new TelNumber(){Id=1,Number = inputString, Type = TelNumberType.UyNomeri});
                Console.Write(">Ishxona tel. nomeri:");
                inputString = Console.ReadLine();
                myContact.telNumbers.Add(new TelNumber() { Id = 2, Number = inputString, Type = TelNumberType.IshNomeri });
                Console.Write(">Fax nomeri:");
                inputString = Console.ReadLine();
                myContact.telNumbers.Add(new TelNumber() { Id = 3, Number = inputString, Type = TelNumberType.FaxNomeri });
                pb.Contacts.Add(myContact);
            }
            String s1 = SerializeObject(pb);
            Console.WriteLine("Natija:");
            Console.WriteLine("Serializatsiya natijasi - ikkilik(binnary) serializatsiya:");
            Console.WriteLine(s1);
            Console.WriteLine("DE-Serializatsiya natijasi:");
            PhoneBook pb2 = (PhoneBook)DeserializeObject(s1);
            Console.WriteLine("------------------ CONTACTS after de-serialization:------------------");
            foreach (var contact in pb2.Contacts)
            {
                Console.WriteLine("Nomi - {0}",contact.Name);
                foreach (var tel in contact.telNumbers)
                {
                    Console.WriteLine("{0} - {1}",tel.Type.ToString(),tel.Number);
                }
                Console.WriteLine("--------------------------------------------------------");

            }
            Console.ReadLine();
           
        }
    }

    [Serializable()]
    internal class PhoneBook
    {
   
        public string Name { get; set; }
        public List<Contact> Contacts { get; set; }

        public PhoneBook()
        {
            this.Contacts = new List<Contact>();
        }
    }
    [Serializable()]
    internal class Contact
    {
        public Guid id { get; set; }
        public string Name { get; set; }
        public List<TelNumber> telNumbers { get; set; }

        public Contact()
        {
            telNumbers = new List<TelNumber>();
        }
    }


    internal enum TelNumberType
    {
        UyNomeri,
        IshNomeri,
        FaxNomeri
    }
    [Serializable()]
    internal class TelNumber
    {
        public int Id { get; set; }
        public TelNumberType Type { get; set; }
        public string Number { get; set; }
    }
}





Dasturni ishga tushirib quyidagi natijaga ega bo'lishimiz mumkin:



Useful LINKS:


No comments:

Post a Comment

Note: only a member of this blog may post a comment.

Tasks and Threads

  Differences Between Task And Thread: 1. The Thread class is used for creating and manipulating a thread in Windows.  2. A Task represents ...