JavaRush /مدونة جافا /Random-AR /كيف يعمل التسلسل في جافا
ramhead
مستوى

كيف يعمل التسلسل في جافا

نشرت في المجموعة
في هذه المقالة، سنشرح ما هو التسلسل وكيف يعمل في جافا. كيف يعمل التسلسل في جافا - 1

مقدمة

تسلسل الكائنات هو قدرة الكائن على تخزين نسخة كاملة منه وأي كائنات أخرى يشير إليها باستخدام دفق إخراج (على سبيل المثال، إلى ملف خارجي). بهذه الطريقة، يمكن إعادة إنشاء الكائن من النسخة المتسلسلة (المحفوظة) لاحقًا عند الحاجة. تسلسل الكائنات، وهي ميزة جديدة تم تقديمها في JDK 1.1، توفر وظيفة لتحويل المجموعات أو الكائنات الفردية، إلى تدفق بت أو مصفوفة بايت، للتخزين أو النقل عبر الشبكة. وكما هو مذكور، يمكن تحويل تدفق بت معين أو مصفوفة بايت مرة أخرى إلى كائنات Java. يحدث هذا بشكل أساسي تلقائيًا بفضل الفئات ObjectInputStreamو ObjectOutputStream. قد يقرر المبرمج تنفيذ هذه الوظيفة من خلال تنفيذ الواجهة Serializableعند إنشاء الفصل. تُعرف عملية التسلسل أيضًا باسم تنظيم الكائنات ، بينما تُعرف عملية إلغاء التسلسل باسم إلغاء التنظيم . التسلسل هو آلية تسمح للكائن بحفظ نسخة منه وجميع الكائنات الأخرى التي يشير إليها الكائن في ملف خارجي باستخدام ملحق ObjectOutputStream. يمكن أن تكون الكائنات المحفوظة عبارة عن هياكل بيانات أو رسوم بيانية أو كائنات فئة JFrameأو أي كائنات أخرى، بغض النظر عن نوعها. في الوقت نفسه، يقوم التسلسل بتخزين معلومات حول نوع الكائن بحيث يتم استخدام هذه المعلومات لاحقًا، عند إلغاء التسلسل، لإعادة إنشاء نوع الكائن الدقيق. لذلك، يوفر التسلسل الإمكانيات التالية:
  • نظام لتخزين الكائنات، أي: حفظ خصائصها إلى ملف خارجي، أو إلى قرص، أو إلى قاعدة بيانات.
  • نظام استدعاء الإجراء عن بعد.
  • نظام توزيع الكائنات، على سبيل المثال، في مكونات البرامج مثل COM، COBRA.
  • نظام لتحديد التغيرات في البيانات المتغيرة مع مرور الوقت.
لفهم مفهوم التسلسل بشكل كامل، يجب أن يكون لديك فهم واضح للمفهومين الآخرين - ثبات الكائن واستمرارية الخيط. وهنا سنتحدث قليلاً عن كل واحد منهم لكي نتذكره. ويتطلب الشرح الكامل لها فصلاً منفصلاً لكل مفهوم من هذه المفاهيم.

تيارات:

يجب على كل برنامج أن يكتب بياناته إلى موقع تخزين أو أنبوب، ويجب على كل برنامج قراءة البيانات من أنبوب أو موقع تخزين. في Java، تُسمى هذه القنوات التي تكتب منها البرامج وتقرأ منها البيانات البيانات باسم Streams ( Stream) . كيف يعمل التسلسل في جافا - 2
الشكل 1. التمثيل الرسومي للخيوط
تنقسم التدفقات بشكل رئيسي إلى نوعين:
  • فئات دفق البايت تسمى *Streams
  • فئات دفق الأحرف تسمى *Reader و *Writer
يحتوي كل تيار لكتابة البيانات على مجموعة من طرق الكتابة. وبالتالي، فإن كل مؤشر ترابط لقراءة البيانات لديه مجموعة مماثلة من أساليب القراءة. بمجرد إنشاء مؤشر الترابط، يجب استدعاء كافة هذه الأساليب.

إصرار

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

تنفيذ الواجهة القابلة للتسلسل

يجب على أي فئة تنفيذ واجهة 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. قراءة الكائنات المتسلسلة أو إلغاء التسلسل
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();
 }
}
يمكن إجراء تسلسل لجميع فئات Java تقريبًا، بما في ذلك فئات AWT. الإطار، وهو نافذة، يحتوي على مجموعة من المكونات الرسومية. إذا كان الإطار متسلسلًا، فإن محرك التسلسل يعتني بهذا ويجري تسلسلًا لجميع مكوناته وبياناته (الموضع والمحتوى وما إلى ذلك). لا يمكن إجراء تسلسل لبعض كائنات فئة Java لأنها تحتوي على بيانات تشير إلى موارد نظام التشغيل المؤقتة. على سبيل المثال الطبقات java.io.FileInputStreamو java.lang.Thread. إذا كان الكائن يحتوي على مراجع لعناصر غير قابلة للتسلسل، فستفشل عملية التسلسل بأكملها وسيتم طرح استثناء NotSerializableException. إذا كان أي كائن يشير إلى مرجع لكائن غير مُسلسل، فيمكن إجراء تسلسل له باستخدام الكلمة الأساسية العابرة . القائمة 4. إنشاء كائنات قابلة للتسلسل باستخدام الكلمة الأساسية العابرة
public class Sclass implements Serializable{
public transient Thread newThread;
//помните, что поток(поток параллельного исполнения) по умолчанию не сериализуемый класс
    private String studentID;
    private int sum;
}

الأمن في التسلسل

يتضمن إجراء تسلسل لفئة في Java تمرير جميع بياناتها إلى ملف خارجي أو قاعدة بيانات عبر الدفق. يمكننا تحديد البيانات التي سيتم تسلسلها متى أردنا ذلك. هناك طريقتان للقيام بذلك:
  • لا يتم إجراء تسلسل لكل معلمة فئة تم تعريفها على أنها عابرة (افتراضيًا، يتم إجراء تسلسل لجميع معلمات الفئة)
  • أو، يتم وضع علامة على كل معلمة من الفئة التي نريد إجراء تسلسل لها بعلامة Externalizable(افتراضيًا، لا يتم إجراء تسلسل لأي معلمات).
لن يتم إجراء تسلسل لحقل البيانات باستخدام ObjectOutputStream، عند استدعائه على كائن، إذا تم وضع علامة عابرة على حقل بيانات هذا الكائن . على سبيل المثال: private transient String password. من ناحية أخرى، للإعلان بشكل صريح عن أن بيانات الكائن قابلة للتسلسل، يجب علينا وضع علامة على الفئة على أنها تكتب وتقرأ بيانات هذا الكائن ExternalizablewriteExternalبشكل صريح .readExteranl

خاتمة

يتم استخدام ميزة تسلسل الكائنات في العديد من الأنظمة الموزعة كوسيلة لنقل البيانات. لكن التسلسل يكشف تفاصيل مخفية، وبالتالي يدمر صحة أنواع البيانات المجردة، والذي بدوره يدمر التغليف. وفي الوقت نفسه، من الجيد معرفة أن بيانات الكائن المتسلسل هي نفس البيانات الموجودة في الكائن الأصلي. وهذه أيضًا فرصة رائعة لتنفيذ واجهة ObjectInputValidationوتجاوز طريقة ما validateObject()، حتى لو تم استخدام عدة أسطر من التعليمات البرمجية. إذا لم يتم العثور على الكائن، فيمكننا طرح استثناء بشكل مناسب InvalidObjectException. المقال الأصلي: كيف يعمل التسلسل في جافا
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION