JavaRush /وبلاگ جاوا /Random-FA /نحوه عملکرد سریال سازی در جاوا
ramhead
مرحله

نحوه عملکرد سریال سازی در جاوا

در گروه منتشر شد
در این مقاله توضیح خواهیم داد که سریال سازی چیست و چگونه در جاوا کار می کند. نحوه عملکرد سریال سازی در جاوا - 1

معرفی

سریال سازی شی، توانایی یک شی برای ذخیره یک کپی کامل از خود و هر شی دیگری که به آن ارجاع می دهد با استفاده از یک جریان خروجی (مثلاً به یک فایل خارجی) است. به این ترتیب، شی می تواند از نسخه سریال (ذخیره شده) کمی بعد در صورت نیاز دوباره ایجاد شود. سریال سازی اشیاء، ویژگی جدیدی است که در JDK 1.1 معرفی شده است، عملکردی را برای تبدیل گروه ها یا اشیاء منفرد، به یک جریان بیت یا آرایه بایت، برای ذخیره سازی یا انتقال از طریق شبکه فراهم می کند. و همانطور که گفته شد، یک جریان بیت معین یا آرایه بایت را می توان دوباره به اشیاء جاوا تبدیل کرد. این عمدتا به لطف کلاس ها ObjectInputStreamو به طور خودکار اتفاق می افتد ObjectOutputStream. برنامه نویس ممکن است تصمیم بگیرد که این قابلیت را با پیاده سازی رابط Serializableدر هنگام ایجاد کلاس پیاده سازی کند. فرآیند سریال‌سازی به عنوان مارشال کردن شی نیز شناخته می‌شود، در حالی که سریال‌زدایی به عنوان unmarshaling شناخته می‌شود . سریال سازی مکانیزمی است که به یک شی اجازه می دهد تا یک کپی از خود و سایر اشیاء ارجاع شده توسط شی را در یک فایل خارجی با استفاده از ObjectOutputStream. اشیاء ذخیره شده می توانند ساختارهای داده، نمودارها، اشیاء کلاس JFrameیا هر شیء دیگری بدون توجه به نوع آنها باشند. در عین حال، سریال‌سازی اطلاعات مربوط به نوع شیء را ذخیره می‌کند تا بعداً، زمانی که از سریال خارج شد، از آن اطلاعات برای بازسازی نوع دقیق شی استفاده شود. بنابراین، سریال‌سازی قابلیت‌های زیر را فراهم می‌کند:
  • سیستمی برای ذخیره اشیاء، به عنوان مثال: ذخیره خصوصیات آنها در یک فایل خارجی، روی دیسک یا پایگاه داده.
  • سیستم تماس رویه از راه دور.
  • یک سیستم توزیع شی، به عنوان مثال، در اجزای نرم افزاری مانند COM، COBRA.
  • سیستمی برای شناسایی تغییرات داده های متغیر در طول زمان.
برای درک کامل مفهوم سریال سازی، باید درک روشنی از دو مفهوم دیگر داشته باشید - ماندگاری شی و ماندگاری نخ. در اینجا برای یادآوری در مورد هر یک از آنها کمی صحبت خواهیم کرد. توضیح کامل آنها نیاز به فصل جداگانه ای برای هر یک از این مفاهیم دارد.

جریان ها:

هر برنامه ای باید داده های خود را در یک محل ذخیره یا لوله بنویسد و هر برنامه باید داده ها را از یک لوله یا محل ذخیره بخواند. در جاوا، به این کانال‌ها که برنامه‌ها در آن می‌نویسند و از آن‌ها داده‌ها را می‌خوانند، Streams ( Stream) می‌گویند . نحوه عملکرد سریال سازی در جاوا - 2
شکل 1. نمایش گرافیکی Threads
جریان ها عمدتاً به دو نوع تقسیم می شوند:
  • کلاس های جریان بایتی به نام *Streams
  • کلاس های جریان کاراکتر به نام *Reader و *Writer
هر جریان نوشتن داده شامل مجموعه ای از روش های نوشتن است. و هر رشته خواندن داده، بر این اساس، مجموعه ای مشابه از روش های خواندن دارد. پس از ایجاد thread، تمام این متدها باید فراخوانی شوند.

ماندگاری

ماندگاری شی، توانایی یک شی برای زنده ماندن یا به عبارت دیگر، "بقا" در اجرای یک برنامه است. این بدان معنی است که هر شیئی که در زمان اجرا ایجاد شده باشد، هر زمان که دیگر از آن شیء استفاده نشود، توسط روبنده JVM از بین می رود. اما اگر Persistence API پیاده‌سازی شود، این اشیاء توسط جاروبرقی JVM از بین نمی‌روند، در عوض به آن‌ها اجازه داده می‌شود که «زندگی کنند»، که دسترسی به آن‌ها را در دفعات بعدی راه‌اندازی برنامه ممکن می‌سازد. به عبارت دیگر، ماندگاری به این معنی است که یک شیء، مستقل از طول عمر برنامه ای که در حال اجرا است، یک عمر وجود دارد. یکی از راه‌های پیاده‌سازی Persistence این است که اشیاء را در جایی در یک فایل یا پایگاه داده خارجی ذخیره کنید و سپس با استفاده از آن فایل‌ها یا پایگاه داده به عنوان منبع، آنها را در زمان دیگری بازیابی کنید. اینجاست که سریال سازی مطرح می شود. تا زمانی که JVM در حال اجرا باشد، هر شی غیر پایداری وجود دارد. اشیاء سریال شده به سادگی اشیایی هستند که به جریان تبدیل می شوند، که سپس در یک فایل خارجی ذخیره می شوند یا برای ذخیره سازی و بازیابی از طریق شبکه منتقل می شوند.

پیاده سازی رابط Serializable

هر کلاسی باید یک رابط java.io.Serializableبرای سریال سازی اشیاء آن کلاس پیاده سازی کند. این رابط Serializableهیچ متد ندارد و فقط کلاس را علامت گذاری می کند تا بتوان آن را به عنوان سریال پذیر شناسایی کرد. فقط فیلدهای یک شی کلاس سریالی را می توان ذخیره کرد. متدها یا سازنده ها به عنوان بخشی از جریان سریال ذخیره نمی شوند. اگر هر شی به عنوان یک مرجع به یک شی دیگر عمل کند، در صورتی که کلاس آن شیء رابط را پیاده سازی کند، فیلدهای آن شی نیز سریالی می شوند Serializable. به عبارت دیگر، نمودار این شیء به دست آمده کاملاً قابل سریال سازی است. گراف شی شامل درخت یا ساختاری از فیلدهای یک شی و اشیاء فرعی آن است. دو کلاس اصلی که به پیاده سازی اینترفیس کمک می کنند Seriliazable:
  • ObjectInputStream
  • ObjectOutputStream
لیست 1. مثالی از یک کلاس ساده برای نشان دادن سریال سازی
import java.io.*;
public class RandomClass implements Serializable {
 // Генерация рандомного значения
 private static int r() {
        return (int)(Math.random() * 10);
 }
    private int data[];
    // Конструктор
public RandomClass() {
        datafile = new int[r()];
        for (int i=0; i<datafile.length; i++)
        datafile[i]=r();
 }
    public void printout() {
 System.out.println("This RandomClass has "+datafile.length+" random integers");
 for (int i=0; i<datafile.length; i++) {
        System.out.print(datafile[i]+":");
        System.out.println();
    }
}
در کد بالا کلاسی ایجاد می شود که قابل سریال سازی است زیرا "علامت گذاری شده" توسط رابط سریال سازی. کلاس هنگام ایجاد یک نمونه از آن، آرایه ای از اعداد صحیح تصادفی ایجاد می کند. کد زیر توانایی نوشتن اشیاء در یک جریان را با استفاده از ObjectOutputStream. این برنامه دارای آرایه ای از اعداد صحیح است، اما برای سریال سازی، ما مجبور نیستیم روی اشیاء داخلی آن تکرار کنیم. رابط Seriliazableبه طور خودکار از این کار مراقبت می کند. لیست 2. یک مثال ساده از سریال سازی اشیاء برای خروجی به یک فایل
import java.io.*;
import java.util.*;
public class OutSerialize {
    public static void main (String args[]) throws IOException {
        RandomClass rc1 = new RandomClass();
        RandomClass rc2 = new RandomClass();
//создание цепи потоков с потоком вывода an object в конце
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("objects.dat"));
        Date now = new Date(System.currentTimeMillis());
//java.util.* был импортирован для использования класса Date
        out.writeObject(now);
        out.writeObject(rc1);
        out.writeObject(rc2);
out.close();
        System.out.println("I have written:");
System.out.println("A Date object: "+now);
        System.out.println("Two Group of randoms");
rc1.printout();
rc2.printout();
 }
}
کد زیر قابلیت های کلاس را نشان می دهد ObjectInputStreamکه داده های سریال شده را از یک فایل خارجی در یک برنامه می خواند. توجه داشته باشید که اشیاء به همان ترتیبی که در فایل نوشته شده اند خوانده می شوند. فهرست 3. خواندن اشیاء سریال یا Deserializing
import java.io.*;
import java.util.*;
public class InSerialize {
 public static void main (String args[]) throws  IOException, ClassNotFoundException {
    ObjectInputStream in =  new ObjectInputStream (new FileInputStream("objects.dat"));
 Date d1 = (Date)in.readObject();
 RandomClass rc1 = (RandomClass)in.readObject();
    RandomClass rc2 = (RandomClass)in.readObject();
    System.out.println("I have read:");
    System.out.println("A Date object: "+d1);
    System.out.println("Two Group of randoms");
    rc1.printout();
rc2.printout();
 }
}
تقریباً تمام کلاس‌های جاوا، از جمله کلاس‌های AWT، قابل سریال‌سازی هستند. یک قاب که یک پنجره است شامل مجموعه ای از اجزای گرافیکی است. اگر فریم سریالی باشد، موتور سریال سازی به این موضوع رسیدگی می کند و تمام اجزا و داده های آن (موقعیت، محتوا و غیره) را سریال می کند. برخی از اشیاء کلاس جاوا را نمی توان سریال سازی کرد زیرا حاوی داده هایی هستند که به منابع زودگذر سیستم عامل ارجاع می دهند. به عنوان مثال کلاس ها java.io.FileInputStreamو java.lang.Thread. اگر یک شی حاوی ارجاعاتی به عناصر غیرقابل سریال‌سازی باشد، کل عملیات سریال‌سازی با شکست مواجه می‌شود و یک استثنا ایجاد می‌شود NotSerializableException. اگر هر شی به مرجعی از یک شی غیر سریالی اشاره دارد، می توان آن را با استفاده از کلمه کلیدی گذرا سریال کرد . فهرست 4. ایجاد اشیاء قابل سریال سازی با استفاده از کلمه کلیدی گذرا
public class Sclass implements Serializable{
public transient Thread newThread;
//помните, что поток(поток параллельного исполнения) по умолчанию не сериализуемый класс
    private String studentID;
    private int sum;
}

امنیت در سریال سازی

سریال سازی یک کلاس در جاوا شامل ارسال تمام داده های آن به یک فایل یا پایگاه داده خارجی از طریق یک جریان است. ما می توانیم داده هایی را که هر زمان که بخواهیم سریال سازی می شوند محدود کنیم. دو راه برای انجام این کار وجود دارد:
  • هر پارامتر کلاسی که به‌عنوان گذرا اعلام می‌شود ، سریال‌سازی نمی‌شود (به‌طور پیش‌فرض، تمام پارامترهای کلاس سریال‌سازی می‌شوند)
  • یا هر پارامتر کلاسی که می‌خواهیم سریال کنیم با یک تگ مشخص می‌شود Externalizable(به طور پیش‌فرض، هیچ پارامتری سریال‌سازی نمی‌شود).
در صورت فراخوانی ObjectOutputStreamیک شیء، اگر فیلد داده گذرا علامت گذاری شده باشد، فیلد داده با . مثلا: private transient String password. از طرف دیگر، برای اعلام صریح داده‌های یک شی به‌عنوان سریال‌پذیر، باید کلاس را به‌عنوان ExternalizablewriteExternalصریحاً readExteranlنوشتن و خواندن داده‌های آن شی علامت‌گذاری کنیم.

نتیجه

ویژگی سریال سازی اشیا در بسیاری از سیستم های توزیع شده به عنوان راهی برای انتقال داده ها استفاده می شود. اما سریال‌سازی جزئیات پنهان را آشکار می‌کند، بنابراین اعتبار انواع داده‌های انتزاعی را از بین می‌برد، که به نوبه خود کپسوله‌سازی را از بین می‌برد. در عین حال، خوب است بدانید که داده‌های شی سریال‌سازی شده همان داده‌ای است که در شی اصلی و اصلی وجود داشت. این همچنین یک فرصت عالی برای پیاده سازی یک رابط ObjectInputValidationو لغو یک روش است validateObject()، حتی اگر چندین خط کد استفاده شود. اگر شی پیدا نشد، می‌توانیم یک استثنا را به درستی پرتاب کنیم InvalidObjectException. مقاله اصلی: سریال سازی در جاوا چگونه کار می کند
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION