Professional Documents
Culture Documents
مقدمة ›
Serializationخطوات الـ ›
Deserializationخطوات الـ ›
مثال شامل ›
serialVersionUIDالمتغير ›
مقدمة
صص البرنامج بالشكل الذي في معظم البرامج التي نستخدمها ,نالحظ أنه يوجد مكان خاص لضبط إعدادات البرنامج يسمح للمستخدم أن يخ ّ
.يريده
أن هذه اإلعدادات تظ ّل محفوظة في البرنامج حتى إذا خرج من البرنامج و فتحه من جديد .بعد أن يقوم المستخدم بضبط إعدادت برنامجه ,نالحظ ّ
فمثالً في البرامج التي تستخدم للكتابة ,تجد في صفحة اإلعدادات أنه بإمكانك تغير أنواع الخطوط المستخدمة في البرنامج ,و تغيير أحجامها و
إلخ لغة من بأكثر التطبيق إستخدام بإمكانك أيضا ً أنه اإلعدادات في تجد وقد و ..ألوانها.
بالنسبة لأللعاب ,غالبا ً ما تجد أنه في صفحة اإلعدادات يمكنك تحديد ما إذا كنت تريد سماع نغمات حماسيّة أثناء اللعب أم ال ,باإلضافة إلى إمكانية
).سهل -متوسّط -صعب -صعب جدا ً ( تحديد مستوى الصوت .أيضا ً أحيانا ً تجد أنه يمكنك تحديد مستوى اللعب
.للحفاظ على إعدادات البرنامج التي ضبطها المستخدم ,نقوم بحفظ هذه اإلعدادات بداخل ملّف و هذا ما ستتعلمه في هذا الدرس
.جيّدا ً حتى تستطيع فهم هذا الدرس ,ألننا سنقوم بتخزن المعلومات في ملف التعامل مع الملفات عليك فهم درس مالحظة
كل متغيّر يملكه ,باإلضافة إلى نوعه و قيمته الحالية إلخ..
عند تنفيذ جميع األوامر الموجودة في البرنامج أو عند الخروج منه ,يتم مسح جميع البيانات المتعلقة بهذا البرنامج من الذاكرة ألنه لم يعد لها
حاجة .أي يتم مسح جميع الكائنات ,المتغيرات و الدوال ,و بالتالي يتوقف أي إتصال قائم بين البرنامج و أشياء خارجية مثل ملف ,شبكة أو قاعدة
..بيانات إلخ
Serializationأهميّة الـ
حالة الكائن المحفوظة في ملف يمكن إستخدامها متى شئنا لخلق الكائن من جديد في الذاكرة.
مشاركة حالة الكائن عبر شبكة ,حيث أنه يمكن استخدام الملف الذي حفظنا فيه حالة الكائن لخلق الكائن في جهاز آخر.
تخزين الصور في قواعد البيانات ( الصورة تحفظ في قاعدة البيانات كـ .) BLOB
إذا ً في حال أردت حفظ معلومات الكائن قبل الخروج من البرنامج يمكنك إنشاء ملف متزامن يحفظ لك حالة الكائن ,و بعدها يمكنك استرجاعها
.عند تشغيل البرنامج من جديد
Serializationخطوات الـ
:إلنشاء كائن من كالس معيّن و حفظ حالته عليك اتباع الخطوات التالية
الكائن الذي تريد حفظ حالته ,يجب أن يكون في األساس مشتق من كالس يفعل implementsلإلنترفيس .Serializable .1
إنشاء ملف إمتداده .serبواسطة الكالس .FileOutputStream .2
تجهيز كائن من الكالس ObjectOutputStreamالذي يستخدم لكتابة حالة الكائن في الملف. .3
نسخ حالة الكائن الموجود في الذاكرة في هذا الملف بواسطة الدالة )(.writeObject .4
.5عند اإلنتهاء من عملية النسخ ,نقوم بقطع ك ّل إتصال قمنا بإجرائه مع هذا الملف.
transientالكلمة المحجوزة
في تعريف ك ّل شيء ال تريده أن ينسخ transientفي حال أردت عدم نسخ جميع األشياء المتعلقة بالكائن في الذاكرة ,عليك وضع الكلمة
.في الملف ,و عندها سيتم تجاهله
Deserializationخطوات الـ
:إلسترجاع حالة الكائن التي ت ّم حفظها في ملف معيّن ,عليك اتباع الخطوات التالية
.1إنشاء كائن فارغ من نفس نوع الكائن الذي نريد إستراجعه حالته من الملف.
.2تجهيز كائن من الكالس FileInputStreamالذي يستخدم إلدخال بيانات ملف محدّد في الذاكرة.
.3تجهيز كائن من الكالس ObjectInputStreamليعيد خلق الكائن في الذاكرة.
.4قراءة حالة الكائن بواسطة الدالّة )( readObjectو تخزينها في الكائن الفارغ الذي قمنا بإنشائه في الخطوة األولى ,و هنا سيكون عليك أن
لتحول نوع الكائن الذي ترجعه الدالّة )( readObjectإلى نوع الكائن الحقيقي ألنّها ترجع الكائن الموجود في تفعل ّ DownCasting
الذاكرة كـ Objectو ليس كنوعه الحقيقي.
.5عند اإلنتهاء من عملية النسخ ,نقوم بقطع ك ّل إتصال قمنا بإجرائه مع هذا الملف.
مثال شامل
Serializable,يطبّق اإلنترفيس Editor,في المثال التالي قمنا بتعرف كالس إسمه و يملك المتغيّرات
: language, encoding, fontSize, fontFamily, autoSave, autoComplete, direction.التالية
Serialization.ألننا ال نريد أن يتم حفظ قيمته عندما نفعل transientقمنا بتعريفه كـ directionالمتغير
Deserialization.و الـ Serializationقمنا فيه بتطبيق مبدأي الـ Testبعدها قمنا بتعريف كالس آخر إسمه
السطر السطر 22من الـ 52إلى مبدأ بتطبيق Deserialization.قمنا
من السطر 59 إلى السطر 90 Serialization.قمنا بتطبيق مبدأ الـ
عند تشغيل البرنامج سيتم خلقه في المجلّد الذي يحتوي user-prefrences.ser.الملف الذي قمنا بتخزين حالة الكائن فيه أسميناه
.على المشروع
.و سنشرح لك معنى هذا السطر الحقا ً 6قم فقط بإضافة الكود التالي في السطر رقم Editorفي حال ظهرت لك مشكلة في الكالس إنتبه
;private static final long serialVersionUID = 1L
مثال
Editor.java
2.
3. import ;java.io.Serializable // Serializable هنا قمنا
باستدعاء اإلنترفيس
4.
5. public class Editor implements { Serializable // Serializable ّق
يطب
direction ّر
قمنا بتعرف المتغي
14.
15. }
Test.java
1. package serialization;
2.
3. import java.io.File; // File هنا قمنا باستدعاء
الكالس
4. import java.io.FileInputStream; // FileInputStream هنا قمنا
باستدعاء الكالس
5. import java.io.FileOutputStream; // FileOutputStream هنا
باستدعاء الكالس
9.
10. public class Test {
11.
12. public static void main (String[] args) {
13.
14. // e إسمهEditor ّ مرة نقوم فيها بتشغيل البرنامج سيتم إنشاء كائن
في كل
من الكالس
15. Editor e = new Editor();
16.
17.
18. // لمعرفة إذا كان يوجد ملف يحفظ حالة الكائن أم الuser-prefrences.ser
بعدها سيتم البحث عن الملف
19. if ( new File( "./user-prefrences.ser" ).exists() )
20. {
21. // منهe موجودا سيحاول البرنامج إستعادة حالة الكائنuser-
prefrences.ser في حال كان الملف
22. try
23. {
24. // في الذاكرةuser-prefrences.ser حتى نستطيع إدخال المعلومات
الموجودة في الملفFileInputStream هنا قمنا بإنشاء كائن نوعه
25. FileInputStream fis = new FileInputStream( "./user-
prefrences.ser" );
26.
27. // في الذاكرةuser-prefrences.ser المحفوظ في الملفEditor
لنتمكن من إعادة خلق كائن الـObjectInputStream هنا قمنا بإنشاء كائن نوعه
28. ObjectInputStream ois = new ObjectInputStream(fis);
29.
30. // e و قمنا بتخزين حالته في الكائنEditor هنا قمنا بقراءة حالة
ّ خلقه في الذاكرة ككائن من الكالس
الكائن الي تم
31. e = (Editor) ois.readObject();
32.
33. // user-prefrences.ser ّ إتصال قمنا
في األخير قمنا بقطع كل
بإجرائه مع الملف
34. fis.close();
35. ois.close();
36.
37. // سيتم طباعة الجملة التالية التي تعني,في حال عدم حدوث أي خطأ
ّت بنجاح ّأ
ن العملية تم
38. System.out.println( "Deserialized data has been created in the
memory" );
46. System.out.println();
47. }
48. catch (IOException | ClassNotFoundException ex)
49. {
50. // في حال حدوث أي خطأ عند محاولة إسترجاع حالة الكائن سيتم
عرضعه
51. System.out.println(ex.getMessage());
52. }
53. }
54.
55.
56.
57.
58. // user-prefrences.ser و حفظها في ملف جديد إسمهe هنا حاولنا تغيير
حالة الكائن
59. try
60. {
61. // ( ) أي قمنا بتغيير إعدادات البرنامجe هنا قمنا بتغيير قيم
الكائن
62. e. language = "arabic" ;
68.
69. // .ser إمتداده,user-prefrences.ser هنا قمنا بإنشاء ملف إسمه
70. = FileOutputStream fos new FileOutputStream( "./user-
;) "prefrences.ser
71.
72. لنتمكن من استخراج حالة أي كائن موجود في // user-prefrences.ser
هنا قمنا بإنشاء كائن نوعه ObjectOutputStreamالذاكرة و وضعها في الملف
73. = ObjectOutputStream oos new ;)ObjectOutputStream(fos
74.
75. eفي الملف user-prefrences.serلحفظ اإلعدادات التي قمنا بإدخالها //
هنا قمنا بنسخ حالة الكائن
76. ;)oos.writeObject(e
77.
78. // user-prefrences.ser ّ إتصال قمنا بإجرائه مع
في األخير قمنا بقطع كل
الملف
79. ;)(oos.close
80. ;)(fos.flush
81. ;)(fos.close
82.
83. // في حال عدم حدوث أي خطأ ,سيتم طباعة الجملة التالية التي تعني ّ
أن
ّت بنجاح
العملية تم
84. System.out.println( "Serialized data has been saved in the project
;) "in a file called user-prefrences.ser
85. }
86. )catch (IOException ex
87. {
88. // في حال حدوث أي خطأ عند نسخ البيانات من الذاكرة إلى الملف سيتم
عرضه
89. ;))(System.out.println(ex.getMessage
90. }
91.
92. }
93.
94. }
المرة األولى التي تقوم فيها بتشغيل البرنامج ستحصل على النتيجة التالية •
.في ّ
Serialized data has been saved in the project in a file called user-prefrences.ser
المرة الثانية التي تقوم فيها بتشغيل البرنامج ستحصل على النتيجة التالية •
.في ّ
Deserialized data has been created in the memory
Language: arabic
Encoding: utf-8
Direction: null
Serialized data has been saved in the project in a file called user-prefrences.ser
محرر و عندها ستتمكن من رؤية user-prefrences.serبما أنّه قد تم إنشاء الملف ّ ي
بنجاح ,يمكنك البحث عنه و فتحه بواسطة أ ّ
.شكل المعلومات التي كانت مسجّلة في الذاكرة
كقيمة nullلذلك تم إعطائه القيمة transient,في الملف ألننا قمنا بتعريفها كـ directionالحظ أنّه لم يت ّم حفظ قيمة المتغيّر
.إفتراضية
serialVersionUIDالمتغير
اإلنترفيس يطبّق كالس فيه Serializableكل خاص إصدار رقم إعطاءه .يتم
serialVersionUID.هذا الرقم يتم تخزينه في المتغير
.حتى لو لم يت ّم تعريفه serialVersionUIDيملك متغيّر إسمه Serializable,إذا ً كل كالس يطبّق اإلنترفيس
.رقم اإلصدار يضمن أن المرسل و المستقبل للملف على الشبكة يملكون نفس نسخة الكالس للكائن المحفوظ في الملف
في حال كان رقم اإلصدار في كالس المرسل مختلف عن رقم اإلصدار في كالس المستقبل يتم رمي إستثناء من
InvalidClassException.النوع
مهم جدا ً عند بناء تطبيق يشارك البيانات بين سيرفر و عميل ,أي يوجد تطبيق على السيرفر و serialVersionUIDإذا ً رقم اإلصدار
.تطبيق عند المستخدم العادي مرتبطان مع بعضهما البعض .سنرى ذلك في الدرس التالي
ليس أمرا ً إجباريا ً في حال كنت تبني برنامج ال تشارك فيه البيانات مع برنامج آخر serialVersionUID ,بشكل عام ,تعريف المتغيّر
أن Eclipse,ألن جافا أصالً ستقوم بتعريفه عنك في حال لم تقم بتعريفه بنفسك ,لكن في بعض بيئات العمل مثل بيئة نالحظ ّ
من جديد في البرنامج ,لذلك ننصحك بتعريفه في serialVersionUIDيظهر تحذير في حال لم نقم بتعريف المتغيّر Complierالـ
.جميع الحاالت ألنه لن يؤثر أصالً على الكود
serialVersionUIDطريقة تعريف المتغيّر
static final long.و لن يشكل ذلك أي فرق هنا ,لكنك مجبر على تعريفه كـ Access Modifierفي البداية يمكنك وضع أي
مثال
1Lوضعنا قيمته Editorفي اإلصدار األول من الكالس •
private static final long serialVersionUID ;= 1L