يمكن أيضًا تنفيذ هذه العملية من خلال الشبكة ، والتي يمكنها أولاً إنشاء كائن على جهاز Windows ، وتسلسلها ، ثم إرسالها إلى جهاز UNIX عبر الشبكة ، ثم إعادة تجميعها بدقة. لماذا يمكن لكل من RMI و Socket و JMS و EJB مرور جافا؟
آلية تسلسل كائن Java لها استخدامان بشكل عام:
Java Javabeans: يجب تكوين معلومات حالة الفول في وقت التصميم. اقرأ حالة الكائن لإعادة بناء الكائن واستعادة حالة البرنامج.
يتيح RMI تشغيل الكائنات على الآلات البعيدة مثل الآلات الأصلية ؛
يمكننا تسلسل الفصول الدراسية عن طريق جعل الفصول الدراسية تنفيذ واجهة java.io.serializable. هذه الواجهة هي واجهة الشركة المصنعة. وهذا هو ، بالنسبة للفئة لتنفيذها ، لا تحتاج الواجهة إلى تنفيذ أي طريقة. يتم استخدامه بشكل أساسي لإخطار الأجهزة الافتراضية Java (JVMs) بأن الكائن يحتاج إلى التسلسل.
هناك بعض النقاط التي نحتاجها لتوضيح ذلك:
لا يمكن تسلسل جميع الفصول.
هناك العديد من الفئات الأساسية في Java التي نفذت واجهات قابلة للتسلسل ، مثل السلسلة ، المتجه ، إلخ. ولكن على سبيل المثال ، لا يقوم Hashtable بتنفيذ الواجهة القابلة للتسلسل.
هناك فئتان رئيسيتان لقراءة أو كتابة كائنات إلى تدفقات: ObjectOutputStream و ObjectInputStream.ObjectOutputStream يوفر طريقة للكتابة المستخدمة لكتابة الكائنات إلى دفق الإخراج ، ويوفر ObjectInputStream طريقة ReadObject لقراءة الكائنات من دفق الإدخال. يجب أن تكون الكائنات التي تستخدم هذه الطرق تسلسلاً. وهذا هو ، يجب أن تكون الواجهة التسلسلية قد تم تنفيذها. إذا كنت ترغب في كتابة كائن علامة تصنيف ، فستحصل على استثناء.
تتمثل عملية التسلسل في كتابة كائنات إلى وقراءة الكائنات من دفق البايت. بعد تحويل حالة الكائن إلى دفق بايت ، يمكنك حفظه في ملف باستخدام فئات دفق البايت المختلفة في حزمة java.io ، أو الأنابيب في مؤشر ترابط آخر ، أو إرسال بيانات الكائن إلى مضيف آخر عبر اتصال شبكة. وظيفة تسلسل الكائن بسيطة للغاية وقوية للغاية ، ويستخدم في RMI ، المقبس ، JMS ، و EJB. إن مشكلة تسلسل الكائن ليست الموضوع الأكثر إثارة في برمجة الشبكة ، ولكنها مهمة للغاية ولها أهمية عملية.
يمكن للتسلسل التسلسل الكائن تنفيذ الكائنات الموزعة. تستخدم التطبيقات الرئيسية مثل: RMI تسلسل الكائنات لتشغيل الخدمات على المضيفين عن بُعد ، تمامًا مثل تشغيل الكائنات على الآلات المحلية.
لا يحتفظ بتسلسل كائن Java فقط ببيانات كائن واحد ، ولكن أيضًا يحفظ بشكل متكرر بيانات كل كائن مشار إليه من قبل الكائن. يمكن كتابة التسلسل الهرمي للكائن بأكمله في دفق بايت أو حفظه في ملف أو تمريره على اتصال شبكة. يمكن استخدام تسلسل الكائن لأداء "نسخ عميق" للكائن ، أي نسخ الكائن نفسه والكائن المشار إليه نفسه. يمكن أن يؤدي تسلسل كائن إلى تسلسل الكائنات الكامل.
تسلسل Java بسيط نسبيًا وعادة ما لا يتطلب كتابة رمز مخصص لحفظ حالة الكائن واستعادته. يمكن تحويل كائنات الفئة التي تنفذ واجهة java.io.serializable إلى أو استردادها من تدفقات البايت دون إضافة أي رمز إلى الفصل. فقط في الحالات النادرة ، هناك رمز مخصص مطلوب لحفظ أو استعادة حالة الكائن. ملاحظة هنا: لا يمكن تسلسل كل فئة ، ولا يمكن تسلسل بعض الفئات.
آلية التسلسل:
ينقسم التسلسل إلى جزأين: التسلسل والتخلص من التسلسل. التسلسل هو الجزء الأول من هذه العملية ، حيث يقسم البيانات إلى دفق بايت للتخزين في ملف أو ناقل حركة عبر شبكة. تخلص من التخلص هو فتح دفق البايت وإعادة بناء الكائن. لا يتطلب تسلسل الكائن فقط تحويل نوع البيانات الأساسي إلى تمثيل بايت ، ولكن في بعض الأحيان استعادة البيانات أيضًا. يتطلب استرداد البيانات مثيلًا للكائن الذي يعيد البيانات. يتم توصيل عملية التسلسل في ObjectOutputStream إلى دفق بايت ، بما في ذلك نوع الكائن ومعلومات الإصدار. أثناء التخلص ، يقوم JVM بإنشاء مثيل كائن يحتوي على معلومات الرأس ، ثم يقوم بنسخ البيانات من دفق بايت الكائن إلى أعضاء بيانات الكائن. دعنا نشرح ذلك في جزأين:
معالجة تدفق الكائن: ( عملية التسلسل وعملية التسلسل)
تحتوي حزمة Java.io على فئتين تقوم بتسلسل الكائنات. ObjectOutputStream مسؤول عن كتابة الكائنات إلى دفق بايت ، ويقوم ObjectInputStream بإعادة بناء الكائنات من دفق بايت.
دعونا أولاً نفهم فئة ObjectOutputStream. يمتد فئة ObjectOutputStream واجهة DataOutput.
طريقة WriteObject () هي الطريقة الأكثر أهمية لتسلسل الكائن. إذا كان الكائن يحتوي على إشارات إلى كائنات أخرى ، فإن طريقة WriteObject () تسلسل هذه الكائنات بشكل متكرر. يحافظ كل كائن ObjectoutPutStream على جدول مرجع كائن مسلسل لمنع إرسال نسخ متعددة من نفس الكائن. (هذا أمر مهم) نظرًا لأن WriteObject () يمكنه إجراء تسلسل مجموعة كاملة من الكائنات المرجعية ، فقد يُطلب من نفس مثيل ObjectOutputStream بطريق الخطأ تخصيص نفس الكائن. في هذا الوقت ، يتم تنفيذ التسلسل المضاد للضادة بدلاً من الكتابة إلى دفق بايت الكائن مرة أخرى.
بعد ذلك ، دعونا نفهم فئة ObjectOutputStream من المثال.
نسخة الكود كما يلي:
// تسلسل تاريخ اليوم في ملف.
fileOutputStream f = new FileOutputStream ("TMP") ؛
ObjectOutputStream S = جديد ObjectOutputStream (F) ؛
S.WriteObject ("اليوم") ؛
S.WriteObject (تاريخ جديد ()) ؛
S.Flush () ؛
الآن ، دعونا نفهم فئة ObjectInputStream. إنه مشابه لـ ObjectOutputStream. يمتد واجهة datainput. تعكس الطرق في ObjectInputStream الطريقة العامة لقراءة أنواع البيانات الأساسية Java في DatainputStream. طريقة ReadObject () تسلط كائن من دفق بايت. في كل مرة يتم استدعاء طريقة ReadObject () ، يتم إرجاع الكائن التالي في الدفق. لا ينقل دفق بايت الكائن رمز الفئة ، ولكنه يتضمن اسم الفصل وتوقيعه. عندما يتلقى ReadObject () الكائن ، يقوم JVM بتحميل الفئة المحددة في الرأس. إذا كان لا يمكن العثور على هذه الفئة ، فإن ReadObject () يرمي ClassNotFoundException. تُستخدم بقية أساليب ObjectInputStream لتخصيص عملية التخلص من التالي.
الأمثلة على النحو التالي:
نسخة الكود كما يلي:
// deserialize كائنات السلسلة وكائنات التاريخ من الملف
FileInputStream في = new FileInputStream ("TMP") ؛
ObjectInputStream s = new ObjectInputStream (in) ؛
سلسلة اليوم = (سلسلة) s.ReadObject () ؛
تاريخ تاريخ = (التاريخ) s.ReadObject () ؛
عملية التسلسل المخصصة:
يمكن عادةً إجراء التسلسل تلقائيًا ، ولكن في بعض الأحيان قد يتم التحكم في العملية. يمكن لـ Java أن تعلن الفئات على أنها قابلة للتسلسل ، ولكن لا يزال بإمكانها التحكم يدويًا في أعضاء البيانات الذين تم إعلانهم على أنهم ثابتون أو عابرون.
مثال: فئة التسلسل البسيطة للغاية.
نسخة الكود كما يلي:
الطبقة العامة simpleserializableClass تنفذ قابلة للتسلسل {
String Stoday = "اليوم:" ؛
تاريخ عابرة dttoday = تاريخ جديد () ؛
}
عند التسلسل ، يجب أن يكون جميع أعضاء البيانات في الفصل قابلين للتسلسل باستثناء أولئك الذين تم إعلانهم على أنهم عابرون أو ثابتون. إعلان المتغير كما يخبر عابر JVM أننا سنكون مسؤولين عن تسلسل الحجج. بعد إعلان عضو البيانات على أنه عابر ، لا يمكن لعملية التسلسل إضافتها إلى دفق بايت الكائن ، ولا توجد بيانات يتم إرسالها من عضو البيانات المؤقتة. عند إلغاء تمييز البيانات بعد ذلك ، يجب إعادة بناء عضو البيانات (لأنه جزء من تعريف الفئة) ، ولكنه لا يحتوي على أي بيانات لأن عضو البيانات هذا لا يكتب أي بيانات إلى الدفق. تذكر أن تدفقات الكائن لا تسلسل تسلسل ثابت أو عابر. يحتاج فصلنا إلى استخدام أساليب WriteObject () و ReadObject () لمعالجة أعضاء البيانات هؤلاء. عند استخدام أساليب WriteObject () و ReadObject () ، يجب عليك أيضًا الانتباه إلى قراءة أعضاء البيانات هذه بالترتيب الذي يتم كتابته فيه.
بعض الرموز حول كيفية استخدام التسلسل المخصص هي كما يلي
نسخة الكود كما يلي:
// أعد كتابة طريقة WriteObject () للتعامل مع الأعضاء العابرة.
public void writeObject (ObjectOutputTream outputStream) يلقي ioException {
outputStream.DefaultWriteObject () ؛ // قم بعمل طريقة ThuctionBriteBject () إلى
// استخدم المنطق المدمج في التسلسل التلقائي.
outputStream.writeObject (osocket.getInetAddress ()) ؛
outputStream.writeint (osocket.getport ()) ؛
}
// أعد كتابة طريقة ReadObject () لتلقي أعضاء عابرين.
private void readObject (ObjectInputStream) يلقي IoException ،
classnotfoundException {
inputStream.DefaultReadObject () ؛ // defaultReadObject () تكمل التسلسل التلقائي
inetaddress oaddress = (inetaddress) inputStream.ReadObject () ؛
int iport = inputStream.ReadInt () ؛
Osocket = مقبس جديد (Oaddress ، iPort) ؛
iid = getId () ؛
dttoday = تاريخ جديد () ؛
}
تخصيص عملية التسلسل تمامًا:
إذا كان الفصل مسؤولاً تمامًا عن التسلسل الخاص به ، فإنه ينفذ الواجهة الخارجية بدلاً من الواجهة القابلة للتسلسل. يتضمن تعريف الواجهة الخارجية القابلة للضرب طريقتين للكتابة على أساس () و readexternal (). يمكن استخدام هذه الطرق للتحكم في كيفية كتابة بيانات الكائنات إلى تدفقات البايت. ، لا يوجد التسلسل التلقائي على الإطلاق. انتبه هنا. تنفذ فئة الإعلان واجهات خارجية مع مخاطر أمنية كبيرة. يتم الإعلان عن أساليب WriteExTernal () و READEXERNAL () ، ويمكن للفئات الخبيثة استخدام هذه الأساليب لقراءة وكتابة بيانات الكائن. إذا كان الكائن يحتوي على معلومات حساسة ، تكون حذراً للغاية. ويشمل ذلك استخدام مآخذ آمنة أو تشفير دفق البايت بأكمله. في هذه المرحلة ، تعلمنا المعرفة الأساسية للتسلسل.