• السابق التالي







  • فبراير
    15
    إنشاء نوع خاص من البيانات و الملفات Object Serialization عن طريق C#.Net
    2011
    كتـب بـواسطة : مهند بندق , التصنيف : دروس في البرمجة , عدد المشاهدات (6794)

    السلام عليكم ورحمة الله وبركاته

    أرحب من جديد بزوار هذه المدونة المحترمين وأرجو ان تكونوا في تمام الصحة و العافية, نعود إليكم مع درس من النوع الدسم و المتقدم  ففي دروس سابقة تطرقت لأساسيات التعامل مع الملفات والمجلدات من قراءة وتخزين واستكشاف وهذا رابط آخر درس بهذا الخصوص:

    التعامل مع الملفات و المجلدات عن طريق C#.Net -الجزء الثالث- الملفات الثنائية

    وهذا الدرس مكمل إلى حد ما بموضوع الملفات و المجلدات حيث سنقوم بإنشاء نوع خاص بنا من البيانات وذلك بتكوين Class نقوم بهندسة بنيتها بدقة لحفظ القيم التي نود تخزينها فيما بعد على هيئة ملف لا يستطيع أي برنامج قراءته إلا برنامجك, بشكل أوضح نقوم بحفظ الكائن أو الفئة الخاصة بنا على هيئة ملف أو أي Stream باختلاف وسيط التخزين.. أعرف ان الموضوع قد يبدو معقد ولكن لنختصر خطوات العمل عدة نقاط:

    1)      تكوين Class تحتوي على مجموعة قيم – متغيرات – تمثل قالب البيانات أو بنية الملف.

    2)      استعمال الـ Class بتكوين كائن جديد منها واسناد قيمه.

    3)      التعامل مع الكائن الذي يحتوي على البيانات وتحويله إلى بيانات ثنائية ثم تخزينها على هيئة ملف.

    4)      لقراءة البيانات نستطيع فتح الملف وأخذ البيانات الثنائية الموجودة فيه ثم تحويل نوعها لنوع الفئة الخاصة بنا .. ومن ثم نستطيع الوصول إلى القيم التي خزناها داخل هذا الملف بدلالة بنيته أي نوع الفئة.

    لنبدأ العمل عن طريق الكود .. أولا يجب علينا استدعاء مجالات الأسماء التالية:

    using System.Runtime.Serialization;

    using System.Runtime.Serialization.Formatters;

    using System.Runtime.Serialization.Formatters.Binary;

     

    ثم سنبدأ ببناء الفئة الخاصة بنا التي يجب أن نورثها من الواجهة IDeserializationCallback وأيضا كتابة attribute وهو [Serializable] لنخبر المترجم أن هذه الفئة نريد حفظ قيمها أي أنها  Serializable objectكما سنلاحظ تكون الطريقة أو الاجراء المسمى OnDeserialization الذي يعتبر زناد يتم سحبه عند قراءة البيانات من الملف أو من Stream اي في لحظة تحويل البيانات الثنائية لدينا إلى نوع الكائن الاصلي ونستطيع كتابة أية إجراءات نود عملها في هذه اللحظة .. و سيكون التكوين المبدئي للـ Class كما يلي

    [Serializable]

    public class MyClassData : IDeserializationCallback

    {

     

     public void OnDeserialization(object sender)

     {

     }

     

    }

    و الآن علينا إنشاء المتغيرات التي ستمثل قيم البيانات التي نود تخزينها

    public string FirstName;

    public string LastName;

    public int Age;

     

    كما نستطيع إضافة Constructor إلى الـ Class يتم إسناد القيم عند تعريف كائن جديد من هذه الفئة عن طريق New

    public MyClassData(string P_FirstName,string P_LastName,int P_Age)

    {

    this.FirstName = P_FirstName;

    this.LastName = P_LastName;

    this.Age = P_Age;

    }

    ونستطيع تكوين متغير في نفس الفئة ولا يشترط أن يتم تخزينه في ملفنا وذلك بكتابة attribute يسمى [NonSerialized] قبل تعريف المتغير كما يلي :

    [NonSerialized]

    public string FullName;

     

    وسنستغل هذا المتغير بإسناد قيمة له عند عملية قراءة الملف وتحويله إلى الكائن الاساسي وذلك عند الاجراء المسمى OnDeserialization كما يلي:

    public void OnDeserialization(object sender)

    {

      FullName = FirstName + " " + LastName;

    }

    الذي سيحصل هو اسناد قيمة الاسم الكامل التي تساوي الاسم الاول + فراغ + الاسم الاخير.

    لنرى الآن الصيغة النهائية لقالب ملفنا

    [Serializable]

    public class MyClassData : IDeserializationCallback

    {

    public MyClassData(string P_FirstName, string P_LastName, int P_Age)

    {

    this.FirstName = P_FirstName;

    this.LastName = P_LastName;

    this.Age = P_Age;

    }

          

    public string FirstName;

    public string LastName;

    public int Age;

    [NonSerialized]

    public string FullName;

     

    public void OnDeserialization(object sender)

    {

    FullName = FirstName + " " + LastName;

    }

    }

     

    يحتوي على ثلاثة حقول وهي الاسم الاول و الاسم الثاني و العمر ... الآن سنقوم باستعمال قالب الملف وتعبئته بالبيانات ثم تخزين بياناته

    لا ننسى استدعاء مجال أسماء :

    using System.IO;

    ثم سنقوم بتعريف كائن من نوع Stream الذي سيمثل ملف على القرص الصلب في حالتنا هذه كما يلي :

    Stream MyStream = File.Open("مسار الملف", FileMode.OpenOrCreate);

     

    وكائن آخر من نوع BinaryFormatter الذي يقوم بعملية تحويل كائننا إلى بيانات ثنائية تمثل قيم متغيراته كما يلي:

    BinaryFormatter MyBinaryFormatter = new BinaryFormatter();

     

    نكون متغير أو كائن جديد من قالب ملفنا – الـ Class التي قمنا بإنشائها - واسناد قيمه أثناء التكوين

    MyClassData MyData = new MyClassData("مهند","بندق", 24);

     

    حيث يمكننا الوصول إلى القيم الموجودة في الفئة هكذا

    MyData.FirstName

    الاسم الاول

    MyData.LastName

    الاسم الاخير

    وهكذا , الآن عملية التخزين عن طريق MyBinaryFormatter تتم باستعمال الاجراء Serialize الذي يستقبل نوعين من الباراميترز وهما Stream و object والذي في حالتنا هذه هو MyData بهذا الشكل:

    MyBinaryFormatter.Serialize(MyStream, MyData);

     ولا ننسى إغلاق Stream بـ

    MyStream.Close();

    هكذا تمت عملية تخزين الملف ونستطيع حفظه في أي مكان وأيضا قراءة محتوياته عن طريق برنامجنا بعكس العملية وهي الوصول إلى الملف عن طريق مساره وبكائن Stream ثم استعمال الكائن BinaryFormatter واستدعاء الدالة Deserialize التي تعود ببيانات الملف وتستقبل باراميتر واحد يمثل Stream ومن ثم تحويل تلك البيانات إلى نوع الفئة الخاصة بنا كما يلي:

    Stream MyStream = File.Open("مسار الملف", FileMode.Open);

    BinaryFormatter MyBinaryFormatter = new BinaryFormatter();

    MyClassData MySavedData =

        (MyClassData)MyBinaryFormatter.Deserialize(MyStream);

     

    وببساطة نستطيع الوصول إلى القيم المخزنة داخل الكائن MySavedData والتعامل معها كما يلي:

    MySavedData.FirstName

    الاسم الاول

    MySavedData.LastName

    الاسم الاخير

    هكذا قد تم شرح كيفية إنشاء كائن يمثل بنية ملف خاصة وتخزينها على هيئة بيانات ثنائية ثم اعادة قراءة تلك البيانات وتحويلها إلى ذلك الكائن ومن ثم الوصول إلى قيمه .. مع ملاحظة أن مكان تخزين نوع بياناتنا هذا لا يشترط أن يكون ملف نستطيع أيضا حفظه في قاعدة البيانات تماما كأي نوع من الملفات مثل الصور و الموسيقى إلى آخره.

    قمت بإنشاء مثال - مفتوح المصدر -  يضم محتويات كل ما تم شرحه في هذا الدرس إضافة إلى استعمال نوع أكثر تعقيد من البيانات مثل الصور , يمكنك تحميل المثال من هذا الرابط.

     

    أرجو أن يكون الشرح واضح وإن اصبت فهو من الله وإن اخطأت فهو من نفسي ومن الشيطان .. نلتقي إن شاء الله في دروس قادمة وإلى ذلك الحين تقبلوا مني أطيب التحيات.

    مهند بندق..

     
    التعليقات (0)




           
    الإسم
    الدولة
    البريد الإلكتروني
    المحتوى  
    أكتب النص الظاهر في الصورة
     





    حقوق النشر محفوظة لـ مهند بندق © 2009 - 2019
    Programmed And Designed By : Mohaned Bondoq
    Copyright © 2009 - 2019