کانال بله, جهت پشتیبانی و اطلاع رسانی کانال بله, جهت پشتیبانی و اطلاع رسانی
عضویت

آموزش Java-آموزش Serialization در جاوا


جاوا مکانیزمی به نام توالی آبجکت (object serialization) ارائه می دهد که در آن آبجکت می تواند به عنوان دنباله ای از بایت ها ارائه شود که حاوی آبجکت داده به همراه اطلاعاتی در مورد نوع آبجکت و نوع داده ی ذخیره شده در آبجکت می باشد.

پس از اینکه یک آبجکت دنباله دار در یک فایل نوشته شد، این آبجکت از فایل خوانده می شود و از این حالت توالی خارج می شود (deserialized) که نوع اطلاعات و بایت هایی که آبجکت را نمایش می دهد و داده ی آن می تواند برای ایجاد مجدد آبجکت در حافظه استفاده شود.

تاثیر گذارتر این است که کل فرایند مستقل از JVM می باشد، بدین معنا که یک آبجکت می تواند روی یک سکو به حالت دنباله دار درآید و روی بخشی کاملا متفاوت از سکو از این حالت خارج شود.

گروه های ObjectInputStream و  ObjectOutputStream جریان های سطح بالایی هستند که حاوی متودهایی برای دنباله دار کردن و یا غیردنباله دار کردن یک آبجکت استفاده می شوند.

گروه ObjectOutputStream حاوی متودهای مختلفی برای نوشتن انواع مختلف داده می باشد، اما یک متود خاص همیشه مشخص می ماند:

public final void writeObject(Object x) throws IOException

متود بالا یک آبجکت را دنباله دار کرده و آن را به جریان خروجی ارسال می کند. به طور مشابه گروه ObjectInputStream  حاوی متود زیر برای خارج کردن یک آبجکت از حالت دنباله دار استفاده می شود (deserializing).

public final Object readObject() throws IOException,

                                 ClassNotFoundException

 

این متود آبجکت بعدی را از جریان بیرون کشیده آن را deserialize می کند. مقدار گزارش شده Object می باشد، بنابراین شما باید آن را به نوع داده ی مناسب خود اختصاص دهید.

برای توضیح چگونگی دنباله دار کردن آبجکت در جاوا، قصد دارم از گروه Employee استفاده کنم که قبلا در مورد آن بحث کردیم. فرض کنید که ما گروه Employee زیر را در اختیار داریم که اینترفیس Serializable  را اجرا می کند.

public class Employee implements java.io.Serializable

{

   public String name;

   public String address;

   public transient int SSN;

   public int number;

   public void mailCheck()

   {

      System.out.println("Mailing a check to " + name

                           + " " + address);

   }

}

 

دقت داشته باشید که برای یک گروه که به طور موفقیت آمیز دنباله دار می شود، دو شرط باید در نظر گرفته شوند:

·         گروه باید اینترفیس java.io.Serializable  را اجرا کند.

·         همه ی فیلدها در گروه باید serializable  باشند. اگر یک فیلد serializable  نباشد، باید به عنوان موقت در نظر گرفته شود.

اگر شما مشتاقید بدانید که یک گروه استاندارد جاوا serializable است یا نه، داکیومنت ها را برای گروه چک کنید. تست بسیار ساده می باشد: اگر گروه java.io.Serializable  را اجرا می کند، بنابراین serializable  می باشد، در غیر این صورت اینطور نیست.

دنباله دار کردن یک آبجکت:

گروه ObjectOutputStream  برای دنباله دار کردن یک آبجکت استفاده می شود. برنامه ی SerializeDemo  زیر یک آبجکت Employee را نمونه گذاری کرده و آن را به شکل یک فایل سریالی در می آورد.

وقتی اجرای برنامه انجام می شود، فایلی به نام employee.ser  ایجاد می شود. برنامه هیچ خروجی تولید نمی کند، اما کد را بررسی کرده و سعی می کند مشخص کند که برنامه در حال انجام چه کاریست.

نکته: در هنگام تبدیل یک آبجکت به یک فایل، تبدیل استاندارد در جاوا این است که به فایل یک .serextension داده شود.

import java.io.*;

 

public class SerializeDemo

{

   public static void main(String [] args)

   {

      Employee e = new Employee();

      e.name = "Reyan Ali";

      e.address = "Phokka Kuan, Ambehta Peer";

      e.SSN = 11122333;

      e.number = 101;

      try

      {

         FileOutputStream fileOut =

         new FileOutputStream("/tmp/employee.ser");

         ObjectOutputStream out = new ObjectOutputStream(fileOut);

         out.writeObject(e);

         out.close();

         fileOut.close();

         System.out.printf("Serialized data is saved in /tmp/employee.ser");

      }catch(IOException i)

      {

          i.printStackTrace();

      }

   }

}

 

Deserialize کردن یک آبجکت:

برنامه ی DeserializeDemo  زیر آبجکت Employee ایجاد شده در برنامه ی SerializeDemo را deserialize می کند. برنامه را مطالعه کرده و سعی کنید خروجی را تعیین کنید:

import java.io.*;

public class DeserializeDemo

{

   public static void main(String [] args)

   {

      Employee e = null;

      try

      {

         FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");

         ObjectInputStream in = new ObjectInputStream(fileIn);

         e = (Employee) in.readObject();

         in.close();

         fileIn.close();

      }catch(IOException i)

      {

         i.printStackTrace();

         return;

      }catch(ClassNotFoundException c)

      {

         System.out.println("Employee class not found");

         c.printStackTrace();

         return;

      }

      System.out.println("Deserialized Employee...");

      System.out.println("Name: " + e.name);

      System.out.println("Address: " + e.address);

      System.out.println("SSN: " + e.SSN);

      System.out.println("Number: " + e.number);

    }

}

 

این برنامه نتیجه ی زیر را به دنبال دارد:

Deserialized Employee...

Name: Reyan Ali

Address:Phokka Kuan, Ambehta Peer

SSN: 0

Number:101

 

در اینجا نکات مهمی وجود دارند که باید ذکر شوند:

·         گروه try/catch  سعی می کند که یک ClassNotFoundException  را بگیرد که توسط متود readObject()  اعلام شده است. برای اینکه یک JVM قادر باشد یک آبجکت را deserialize کند، باید بتواند bytecode  را برای گروه پیدا کند. اگر JVM در طی deserialization  کردن یک آبجکت نتواند یک گروه را پیدا کند، یک ClassNotFoundException  وارد می کند.

·         دقت داشته باشید که مقدار گزارش شده از readObject()  بخشی از یک مرجع Employee می باشد.

·         وقتی که آبجکت به حالت سریالی در آمد، مقدار فیلد SSN عدد 11122333 بود، اما به خاطر اینکه فیلد موقت است، این مقدار به جریان خروجی ارسال نشد. فیلد SSN از آبجکت deserialized Employee  مقدار 0 می باشد.

1394/07/27 6953 0
نظرات شما

نظرات خود را ثبت کنید...