القائمة الرئيسية

الصفحات

معالجة الأخطاء والملفات في جافا

مفهوم الإستثناءات في جافا

استثناءات: تعني Exceptions في البرمجة, و الإستثناء عبارة عن خطأ يحدث أثناء تشغيل البرنامج يؤدي إلى إيقافه بشكل غير طبيعي.

ظهور خطأ يؤدي إلى إيقاف البرنامج هو أمر سيئ جداً لأنه يؤدي إلى نفور عدد كبير من المستخدمين و عدم رغبتهم في العودة إلى استخدام هذا البرنامج مجدداً.

في هذا الدرس ستتعلم كيف تتجنب حدوث أخطاء في البرامج التي تكتبها, و فعلياً ستتعلم كيف تلتقط هذه الأخطاء في حال حدثت لجعل البرنامج شغال دائماً في نظر المستخدم و لا يظهر له أي أخطاء.


بعض الأسباب التي تسبب حدوث إستثناء

  • في حال إدخال قيمة لا تتطابق مع نوع المتغير الذي ستخزن فيه.

  • في حال إدخال رقم index غير موجود في مصفوفة أو في متغير نوعه String.

  • في حال كان البرنامج يتصل بالشبكة و فجأةً إنقطع الإتصال.

  • في حال كان البرنامج يحاول قراءة معلومات من ملف نصي, و كان هذا الملف غير موجود.



فئات الإستثناءات

الإستثناءات قد تحدث بسبب المستخدم (User), أو المبرمج (Programmer), أو بسبب الأجهزة المستخدمة (Physical Resources).

بناءً على هذا, تم تقسيم الإستثناءات إلى ثلاث فئات أساسية:

  • Checked Exception: تعني خطأ برمجي يحدث أثناء ترجمة البرنامج (أي قبل تشغيل الكود).

  • Unchecked Exception: تعني خطأ منطقي يحدث أثناء تشغيل البرنامج.

  • Error: تعني خطأ يحدث بسبب الجهاز الذي نحاول تشغيل البرنامج عليه.



Checked Exception

Checked Exception تعني إستثناء يحدث أثناء ترجمة الكود, و هنا يكون الخطأ من المبرمج لأن الكود الذي كتبه يوجد فيه مشكلة ظاهرة من الأساس.

الآن في حال قمنا بتعريف متغير نوعه int, ثم قمنا بإعطائه نص كقيمة, سنلاحظ أنه سيظهر لنا خطأ قبل تشغيل البرنامج, و في حال حاولنا تشغيله, سيظهر الخطأ عندما يحاول ترجمة الكود.

مثال

Main.java
	  public class Main {

	  public static void main(String[] args) {

	  int a;
	  a = "this is incompatible type, 'a' should be String";

	  }

	  }
	

سيظهر الخطأ التالي إذا قمنا بتشغيل البرنامج.

Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - incompatible types: java.lang.String cannot be converted to int

هذا الخطأ يعني أن هناك مشكلة في النوع المستخدم لتخزين البيانات.
ثم أخبرنا بسبب المشكلة و هي أنه لا يمكن تحويل الـ String لـ int, أي لا يمكن تخزين قيمة نوعها String في متغير نوعه int.



Unchecked Exception

(Unchecked Exception) تعني إستثناء يحدث أثناء تشغيل البرنامج و يسمى أيضاً (Runtime Exception), و هو يتضمن الـ (Programming Bugs) و التي تعني أخطاء منطقية (Logical Errors) أو أخطاء سببها عدم إستخدام الأشياء المعرفة في لغة البرمجة بالشكل الصحيح (APIs errors).

الآن في حال قمنا بتعريف مصفوفة نوعها int تتألف من 5 عناصر, ثم قمنا بطباعة قيمة عنصر غير موجود فيها ( مثل العنصر رقم 10 ). سنلاحظ أنه سيظهر الخطأ أثناء تشغيل البرنامح و ليس أثناء ترجمة الكود, و السبب أنه سيكتشف عدم وجود عنصر يحمل الـ index رقم 10 بعد أن يتم إنشاء هذه المصفوفة في الذاكرة ( أي بعد ترجمة الكود و تنفيذه ).

إذاً حدوث خطأ أثناء التشغيل يعني أن الخطأ لا يكتشف إلا أثناء محاولة تنفيذ الأوامر.

مثال

	  public class Main {

	  public static void main(String[] args) {

	  int[] a = { 1, 2, 3, 4, 5 };
	  System.out.println( a[10] );

	  }

	  }
	

سيظهر الخطأ التالي إذا قمنا بتشغيل البرنامج.

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10

هذا الخطأ يعني أن العنصر ليس موجود في المصفوفة.
ثم أخبرنا بسبب المشكلة و هي أنه لم يجد عنصر يحمل الـ index رقم 10.



Error

Error تعني خطأ يحدث بسبب الجهاز الذي نحاول تشغيل البرنامج عليه, لا علاقة أبداً للبرنامج بهذا الخطأ.

فمثلاً إذا إمتلأت ذاكرة الجهاز الذي يعمل عليه البرنامج سيحدث خطأ, و هو أن نظام التشغيل لا يقدر أن يشغل هذا البرنامج لأن ذاكرة الجهاز ممتلئة. و عندها سيظهر الرسالة التالية لتوضيح الخطأ JVM is out of Memory

لذلك تجد بعض البرامج تحفظ الأشياء التي يفعلها المستخدم كل مدة معينة, و هكذا لن يقلق المستخدم إذا توقف البرنامج الذي يعمل عليه فجأةً, لأن هذا البرنامج في نظره قوي فهو يحفظ له بياناته كل مدة و يتيح له استردادها إذا حدث خطأ ما متى شاء.

بناء الإستثناءات في جافا

تم تقسيم الإستثناءات في جافا إلى عدة أنواع و كل نوع تم تمثيله في كلاس منعزل.
جميع هذه الكلاسات ترث من كلاس أساسي إسمه Exception.
الكلاس Exception بدوره يرث من كلاس إسمه Throwable.

إذاً, أي كلاس يرث من الكلاس Exception هو كلاس يمثل إستثناء معين.

الأخطاء التي سببها الأجهزة و التي تسمى Errors, تم إنشاء كلاس خاص لهم إسمه Error و هو يرث مباشرةً من الكلاس Throwable.


ملاحظة

لا تقلق بتاتاً إذا لم تفهم أي شيء الآن ستفهم الوراثة في دروس لاحقة, لكننا ذكرنا لك كلمة "وراثة" لأنها ستمر معك لاحقاً في هذا الدرس.


فكرة عامة عن الوراثة
إذا قلنا الكلاس B يرث من الكلاس A. فهذا يعني أن الكلاس B أصبح يملك نسخة من الأشياء الموجودة في الكلاس A.


تم بناء الإستثناءات بشكل منظم كما في الصورة التالية.


لمشاهدة أغلب الإستثناءات الـ checked و unchecked التي يواجهها المبرمجين

أدخل هنا »

إلتقاط الإستثناء في جافا

إلتقاط الإستثناء يسمى Catching Exception, و هو عبارة عن طريقة تسمح لك بحماية البرنامج من أي كود تشك بأنه قد يسبب أي خطأ باستخدام الجملتين try و catch.

أي كود مشكوك فيه يجب وضعه بداخل حدود الجملة try.
الجملة catch عبارة عن دالة يمكنك من خلالها معرفة كل شيء عن الخطأ الذي حدث.


طريقة تعريف الجمل try و catch


	try {
	// Protected Code
	// هنا نكتب الأوامر التي قد تولد إستثناء
	}
	catch(ExceptionType e) {
	// Error Handling Code
	// برمي إستثناء try هنا نكتب أوامر تحدد للبرنامج ماذا يفعل إذا قامت الـ
	} 
  

الكود الذي نضعه بداخل الجملة try يسمى Protected Code و هذا يعني أن البرنامج محمي من أي خطأ قد يحدث بسبب هذا الكود.
الكود الذي نضعه بداخل الجملة catch يسمى Error Handling Code و يقصد منها الكود الذي سيعالج الإستثناء الذي قد يتم إلتقاطه.

عندما تضع الكود بداخل حدود الجملة try فأنت بذلك تقوم بتجربة هذا الكود, و ذلك يعني أن جميع الأوامر الموضوعة فيها ستنفذ بشكل عادي جداً, و في حال حدثت أي مشكلة في الكود, ستقوم الجملة try بتمرير الإستثناء الذي يمثل هذه المشكلة كـ argumentإلى الدالة catch ليتم معالجته بدل أن تظهر أمام المستخدم.

الإستثناء الذي تقوم الجملة try برميه عبارة عن كائن من إحدى الكلاسات التي ترث من الكلاس Exception.


ملاحظة

عندما تستخدم الجملة try حتى لو لم تضع بداخلها أي كود, فأنت مجبر على وضع الجملة catch أو finally بعدها.
كما أنه بإمكانك وضع العدد الذي تريده من الجملة catch و سترى ذلك و ستتعرف على الجملة finally لاحقاً في هذا الدرس.


مثال

Main.java
	  public class Main {

	  public static void main(String[] args) {

	  try {                              // try هنا قمنا بتجربة الكود الموجود بداخل الجملة
	  int[] a = new int [5];         // هنا قمنا بإنشاء مصفوفة تتألف من 5 عناصر
	  System.out.println( a[10] );   // catch هنا حاولنا عرض قيمة عنصر غير موجود في المصفوفة, لذلك سيحدث خطأ, مما سيؤدي رمي إستثناء إلى الدالة
	  }
	  catch( Exception e ) {                                // e هنا سيتم إلتقاط الإستثناء, ثم تخزينه في الكائن
	  System.out.println( "Exception thrown: " + e );   // لنعرف طبيعة الخطأ الذي حدث e هنا قمنا بعرض محتوى الكائن
	  }

	  // بعد الإنتهاء من تجربة الكود سيتم تنفيذ باقي الأوامر الموجودة في البرنامج
	  System.out.println( "The program still work properly" );

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

Exception thrown: java.lang.ArrayIndexOutOfBoundsException: 10
The program still work properly

إذا وضعنا الكلاس Exception كباراميتر للدالة catch, فهذا يعني أن أي إستثناء سترميه الدالة try ستقوم الدالة catch بالتقاطه.

في المثال السابق كان بإمكانك وضع الكلاس ArrayIndexOutOfBoundsException بدل الكلاس Exception, لأننا بعد تجربة الكود عرفنا أن نوع الخطأ الذي قد يرمى بسبب هذا الكود نوعه ArrayIndexOutOfBoundsException.

إذاً إذا كنت لا تعرف طبيعة الخطأ الذي قد يحدث ضع الكلاس Exception في الدالة catch لأن الكلاس Exception يعتبر الكلاس الأساسي و الإفتراضي لجميع الأخطاء التي قد تحدث.

وضع عدة جمل catch في جافا

أحياناً الكود الواحد قد يسبب عدة أخطاء, ففي هذه الحالة ستضطر إلى معالجة كل خطأ قد يحدث على حدى ليستمر البرنامج في العمل بشكل طبيعي.

إذاً يمكنك وضع العدد الذي تريده من الجملة catch بعد الجملة try.


طريقة وضع أكثر من catch


	try {
	// Protected Code
	// هنا نكتب الأوامر التي قد تولد إستثناء
	}
	catch(ExceptionType1 e1) {
	// Error Handling Code For ExceptionType1
	// ExceptionType1 برمي إستثناء من النوع try هنا نكتب أوامر تحدد للبرنامج ماذا يفعل إذا قامت الـ
	}
	catch(ExceptionType2 e2) {
	// Error Handling Code For ExceptionType2
	// ExceptionType2 برمي إستثناء من النوع try هنا نكتب أوامر تحدد للبرنامج ماذا يفعل إذا قامت الـ
	}
	catch(ExceptionType3 e3) {
	// Error Handling Code For ExceptionType3
	// ExceptionType3 برمي إستثناء من النوع try هنا نكتب أوامر تحدد للبرنامج ماذا يفعل إذا قامت الـ
	}
  

هنا قمنا بوضع ثلاث جمل catch و طبعاً كان بإمكاننا وضع العدد الذي نريده.


طريقة تعامل البرنامج مع الجمل catch

إذا قامت الجملة try برمي إستثناء, سيتم إرساله إلى جملة الـ catch الأولى, بعدها سيتم مقارنة نوع الإستثناء المرمي مع نوع الإستثناء الموضوع كباراميتر في الدالة, إذا كان نوع الإستثناء المرمي هو نفسه نوع الإستثناء الموضوع كباراميتر, سيتم معالجة الخطأ الذي حدث بداخل هذه الـ catch.

إذا كان نوع الإستثناء المرمي غير النوع الموضوع كباراميتر, سيتم الإنتقال إلى جملة الـ catch التالية و تنفيذ نفس الخطوات السابقة.

في حال تم إيجاد إستثناء يطابق الإستثناء المرمي, سيتم تنفيذ جميع الأوامر الموجودة في جملة الـ catch و بعدها سيتخطى البرنامج جميع جمل الـ catch الموجودة بعدها و يكمل باقي الأوامر الموجودة في البرنامج.

و في حال لم يتم إيجاد أي إستثناء يطابق الإستثناء المرمي, سيتوقف البرنامج و يظهر الخطأ الذي حدث.

مثال

Main.java
	  public class Main {

	  public static void main(String[] args) {

	  String s = "1234567891011121314151617181920212223";
	  int a;

	  try {
	  System.out.println( "s.charAt(28): " + s.charAt(28) );   // s رقم 28 في النص index هنا حاولنا عرض الحرف الموجود على الـ
	  a = Integer.parseInt(s);                                 // int لقيمة s هنا حاولنا تحويل قيمة
	  }
	  catch( StringIndexOutOfBoundsException e1 ) {                // e1 بعدها تقوم بتخزينه في الكائن StringIndexOutOfBoundsException تلتقط الإستثناء الذي نوعه catch هذه الـ
	  System.out.println( "Index is not exist in the string!" );
	  }
	  catch( NumberFormatException e2 ) {                          // e2 بعدها تقوم بتخزينه في الكائن NumberFormatException تلتقط الإستثناء الذي نوعه catch هذه الـ
	  System.out.println( "Can't convert 's' to a number because is to long!" );
	  }
	  catch( Exception e3 ) {                                      // e3 تلتقط أي إستثناء آخر قد يحدث نسينا ذكره, بعدها تقوم بتخزينه في الكائن catch هذه الـ
	  System.out.println( "Exception thrown: " + e3 );
	  }

	  // بعد الإنتهاء من تجربة الكود سيتم تنفيذ باقي الأوامر الموجودة في البرنامج
	  System.out.println( "The program still work properly" );

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

s.charAt(28): 9
Can't convert 's' to a number because is to long!
The program still work properly

يمكنك أيضأ وضع أكثر من إستثناء بداخل نفس الجملة catch باستخدام العامل | و الذي يعني " أو "
عندها إذا رمت الجملة try أي إستثناء من الإستثناءات الموجودة في الجملة catch سيتم معالجة الإستثناء فيها.

مثال

Main.java
	  public class Main {

	  public static void main(String[] args) {

	  String s = "1234567891011121314151617181920212223";
	  int a;

	  try {
	  System.out.println( "s.charAt(28): " + s.charAt(28) );            // s رقم 28 في النص index هنا حاولنا عرض الحرف الموجود على الـ
	  a = Integer.parseInt(s);                                          // int لقيمة s هنا حاولنا تحويل قيمة
	  }
	  catch( StringIndexOutOfBoundsException|NumberFormatException e1 ) {   // e1 بعدها تقوم بتخزينه في الكائن ,NumberFormatException أو StringIndexOutOfBoundsException تلتقط الإستثناء إذا كان نوعه catch هذه الـ
	  System.out.println( "The string 's' throw: " +e1 );
	  }
	  catch( Exception e2 ) {                                               // e2 تلتقط أي إستثناء آخر قد يحدث نسينا ذكره, بعدها تقوم بتخزينه في الكائن catch هذه الـ
	  System.out.println( "Exception thrown: " + e2 );
	  }

	  // بعد الإنتهاء من تجربة الكود سيتم تنفيذ باقي الأوامر الموجودة في البرنامج
	  System.out.println( "The program still work properly" );

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

s.charAt(28): 9
The string 's' throw: java.lang.NumberFormatException: For input string: "1234567891011121314151617181920212223"
The program still work properly

الجملة finally في جافا

الجملة finally تأتي بعد الجملتين try و catch.
الكود الموضوع في الجملة finally يتنفذ دائماً, أي في حال حدث إستثناء أو لم يحدث فإنه سيتنفذ.

الجملة finally تستخدم لتنظيف الكود, بمعنى أنها تستخدم للتخلص من أي كود لم يعد البرنامج يحتاج إليه.


مكان وضع الجملة finally


	try {
	// Protected Code
	}
	catch(ExceptionType1 e1) {
	// Error Handling Code For ExceptionType1
	}
	catch(ExceptionType2 e2) {
	// Error Handling Code For ExceptionType2
	}
	catch(ExceptionType3 e3) {
	// Error Handling Code For ExceptionType3
	}
	finally {
	// Optional Cleanup Code
	// هنا نقوم بكتابة أوامر للتخلي عن أي شيء لم يعد البرنامج بحاجة له
	} 
  

مثال

Main.java
	  public class Main {

	  public static void main(String[] args) {

	  String s = "1234567891011121314151617181920212223";
	  int a;

	  try {
	  System.out.println( "s.charAt(28): " + s.charAt(28) );   // s رقم 28 في النص index هنا حاولنا عرض الحرف الموجود على الـ
	  a = Integer.parseInt(s);                                 // int لقيمة s هنا حاولنا تحويل قيمة
	  }
	  catch( StringIndexOutOfBoundsException e1 ) {                // e1 بعدها تقوم بتخزينه في الكائن StringIndexOutOfBoundsException تلتقط الإستثناء الذي نوعه catch هذه الـ
	  System.out.println( "Index is not exist in the string!" );
	  }
	  catch( NumberFormatException e2 ) {                          // e2 بعدها تقوم بتخزينه في الكائن NumberFormatException تلتقط الإستثناء الذي نوعه catch هذه الـ
	  System.out.println( "Can't convert 's' to a number because is to long!" );
	  }
	  catch( Exception e3 ) {                                      // e3 تلتقط أي إستثناء آخر قد يحدث نسينا ذكره, بعدها تقوم بتخزينه في الكائن catch هذه الـ
	  System.out.println( "Exception thrown: " + e3 );
	  }
	  finally {                                                    // تتنفذ في حال حدث إستثناء أو لم يحدث finally الجملة
	  System.out.println( "finally codes always execute" );
	  }

	  // بعد الإنتهاء من تجربة الكود سيتم تنفيذ باقي الأوامر الموجودة في البرنامج
	  System.out.println( "The program still work properly" );

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

s.charAt(28): 9
Can't convert 's' to a number because is to long!
finally codes always execute
The program still work properly

ستعرف فائدة الجملة finally في دروس لاحقة عندما تتعامل مع الملفات, الشبكات, قواعد البيانات إلخ..

  • إذا كان البرنامج يقرأ محتوى ملف نصي, سيكون عليك التأكد من إغلاق الملف بعد الإنتهاء من قرائته.

  • إذا كان البرنامج يقرأ بيانات من قاعدة بيانات , سيكون عليك التأكد من إغلاق قاعدة البيانات بعد الإنتهاء من التعامل معها.

  • إذا كان البرنامج يتصل بالشبكة , سيكون عليك التأكد من إغلاق الإتصال بعد الإنتهاء من التعامل معها.



ملاحظات مهمة

  • لا يمكنك إستخدام الجملة try إذا لم تضع بعدها الجملة catch أو الجملة finally.

  • لا يمكنك وضع الجملة catch إذا لم تستخدم قبلها الجملة try.

  • الجملة finally توضع إختيارياً.

  • لا يمكنك وضع أي كود بين الجمل try و catch و finally.

دوال الكلاس Exception في جافا

هنا وضعنا بعض الدوال الموجودة في الكلاس Exception و التي يمكن إستخدامها لمعرفة الأخطاء التي حدثت في البرنامج.

الدالة مع تعريفها
public String getMessage ترجع رسالة بسيطة تظهر لنا الخطأ الذي حدث.
public String toString() ترجع إسم كلاس الإستثناء الذي حدث مضافاً إليه نتيجة الخطأ التي ترجعها الدالة getMessage().
public void printStackTrace() يستخدمها المبرمج لمعرفة الأخطاء التي قد تحدث أثناء تشغيل البرنامج, و هي مفيدة جداً لأنها تظهر الخطأ الذي حدث كما هو بكامل تفاصيله. إذاً هذه الدالة تستخدم للـ Debugging.


المثال الأول

في هذا المثال سنستخدم الدالة getMessage() لمعرفة سبب الخطأ الذي حدث فقط.

Main.java
	  public class Main {

	  public static void main(String[] args) {

	  String s = "abcd 12345";
	  int a;

	  try {
	  a = Integer.parseInt(s);                 // int لقيمة s هنا حاولنا تحويل قيمة
	  }
	  catch( Exception e ) {                       // e تلتقط أي إستثناء قد يحدث, بعدها تقوم بتخزينه في الكائن catch هذه الـ
	  System.out.println( e.getMessage() );    // لمعرفة الخطأ الذي حدث getMessage() هنا قمنا باستخدام الدالة
	  }

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

For input string: "abcd 12345"


المثال الثاني

في هذا المثال سنستخدم الدالة toString() لمعرفة سبب الخطأ الذي حدث و إسم الكلاس الذي يمثل الإستثناء الذي حدث.

Main.java
	  public class Main {

	  public static void main(String[] args) {

	  String s = "abcd 12345";
	  int a;

	  try {
	  a = Integer.parseInt(s);                // int لقيمة s هنا حاولنا تحويل قيمة
	  }
	  catch( Exception e ) {                      // e تلتقط أي إستثناء قد يحدث, بعدها تقوم بتخزينه في الكائن catch هذه الـ
	  System.out.println( e.toString() );     // لمعرفة الخطأ الذي حدث toString() هنا قمنا باستخدام الدالة
	  }

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

java.lang.NumberFormatException: For input string: "abcd 12345"


المثال الثالث

في هذا المثال سنستخدم الدالة printStackTrace() لمعرفة تفاصيل الخطأ الذي حدث بتفصيل.

Main.java
	  public class Main {

	  public static void main(String[] args) {

	  String s = "abcd 12345";
	  int a;

	  try {
	  a = Integer.parseInt(s);    // int لقيمة s هنا حاولنا تحويل قيمة
	  }
	  catch( Exception e ) {          // e تلتقط أي إستثناء قد يحدث, بعدها تقوم بتخزينه في الكائن catch هذه الـ
	  e.printStackTrace();        // لمعرفة الخطأ الذي حدث printStackTrace() هنا قمنا باستخدام الدالة
	  }

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

java.lang.NumberFormatException: For input string: "abcd 12345"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at testexceptions.Main.main

الكلمتين throws و throw في جافا

إذا قمت بتعريف دالة و أردت لهذه الدالة أن ترمي إستثناء إذا حدث شيء معين فعليك وضع الكلمة throws بعد أقواس الباراميترات ثم تحديد نوع الإستثناء الذي قد ترميه الدالة, و إذا قمت مسبقاً بتعريف إستثناء يمكنك جعل الدالة تقوم برميه.

الكلمة throw تستخدم لتحديد نوع الإستثناء الذي سيرسل إلى الجملة catch.
الكلمة throws تستخدم لتحديد نوع الإستثناء الذي قد تقوم الدالة برميه في حال كنت تريد تجربة الكود و معالجته في مكان إستدعاء الدالة.


المثال الأول

الأسلوب المتبع هنا يسمى Exception Thrower/Exception Catcher.

في هذا المثال قمنا ببناء دالة ترمي إستثناء و تعالجه بداخلها في حال قمنا بإعطائها عمر أكبر من 63.

Main.java
	  public class Main {

	  public static void main(String[] args) {
	  // مما يعني أنها ستقوم برمي إستثناء argument هنا قمنا باستدعاء الدالة و أعطيناها القيمة 70 كـ
	  checkAge(70);
	  }


	  public static void checkAge (int age) {
	  // و النص الذي وضعناه بين القوسين عبارة عن شرح للمشكلة التي قد تحدث و هو الذي سيتم عرضه catch أكبر من 63 سيتم رمي إستثناء إلى الدالة age هنا الدالة تقوم بتجربة الكود و في حال كانت قيمة
	  try {
	  if(age > 63) {
	  throw new Exception("you are too old!");
	  }
	  }
	  // ثم تقوم بعرض نوع الخطأ e تلتقط أي إستثناء قد يحدث, بعدها تقوم بتخزينه في الكائن catch هذه الـ
	  catch( Exception e ) {
	  System.out.println( e.getMessage() );
	  }
	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

	  you are too old!
	

إذاً لا نحتاج إلى إستخدام الكلمة throws إلا إذا أردنا وضع الدالة بداخل الجملة try عند إستدعائها.



المثال الثاني

الأسلوب المتبع هنا يسمى Exception Thrower/Exception Propagator.

في هذا المثال قمنا ببناء دالة ترمي إستثناء يعالج في مكان الإستدعاء في حال قمنا بإعطائها عمر أكبر من 63.

Main.java
	  public class Main {

	  public static void main(String[] args) {
	  // لأنها قد ترمي إستثناء try و وضعناها بداخل الجملة argument هنا قمنا باستدعاء الدالة و أعطيناها القيمة 70 كـ
	  try {
	  checkAge(70);
	  }
	  // ثم تقوم بعرض نوع الخطأ e تلتقط أي إستثناء قد يحدث, بعدها تقوم بتخزينه في الكائن catch هذه الـ
	  catch( Exception e ) {
	  System.out.println( e.getMessage() );
	  }
	  }


	  // و النص الذي وضعناه بين القوسين عبارة عن شرح للمشكلة التي قد تحدث و هو الذي سيتم عرضه catch أكبر من 63 سيتم رمي إستثناء إلى الدالة age هنا الدالة تقوم بتجربة الكود عند إستدعئها و في حال كانت قيمة
	  public static void checkAge (int age) throws Exception{
	  if(age > 63) {
	  throw new Exception("you are too old!");
	  }
	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

	  you are too old!
	

إذا أردت إنشاء دالة ترمي أكثر من إستثناء, عليك فقط وضع فاصلة بين كل نوعين, و في حال لم يتم التعرف على الإستثناء الذي قمت باستخدامه, يجب أن تفعل له import فقط.


المثال الثالث

الأسلوب المتبع هنا يسمى Exception Thrower/Exception Propagator.

في هذا المثال قمنا ببناء دالة قد ترمي إستثناءين يتم معالجتهما في مكان الإستدعاء.

Main.java
	  public class Main {

	  public static void main(String[] args) {

	  // لأنها قد ترمي إستثناء try و وضعناها بداخل الجملة argument و أعطيناها القيمة 0 كـ checkAge() هنا قمنا باستدعاء الدالة
	  try {
	  checkAge(0);
	  }
	  // و بعدها تقوم بعرض الخطأ e1 ثم تقوم بتخزينه في الكائن ArithmeticException تلتقط أي إستثناء من النوع catch هذه الـ
	  catch( ArithmeticException e1 ) {
	  System.out.println( e1.getMessage() );
	  }
	  // ثم تقوم بعرض نوع الخطأ e2 تلتقط أي إستثناء آخر قد يحدث ثم تقوم بتخزينه في الكائن catch هذه الـ
	  catch( Exception e2 ) {
	  System.out.println( e3.getMessage() );
	  }

	  }


	  // Exception أو من النوع ArithmeticException هنا قلنا أن الدالة قد ترمي إستثناء من النوع
	  // ArithmeticException أصغر أو تساوي صفر سيتم رمي إستثناء من النوع argument هنا الدالة تقوم بتجربة الكود عند إستدعائها و في حال كانت القيمة التي نمررها لها كـ
	  // Exception و إذا حدث أي إستثناء آخر سيتم رمي إستثناء من النوع
	  public static void checkAge (int age) throws ArithmeticException, Exception{
	  if(age <= 0) {
	  throw new ArithmeticException("This is ArithmeticException");
	  }
	  else{
	  System.out.println( 100/age );
	  }
	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

	  This is ArithmeticException
	

إنشاء Exception جديد و إستخدامه في جافا

في البداية ننصح بالعودة لهذه الفقرة بعد دراسة الوارثة, لكي يتم فهم الكود بشكل كامل.


خطوات إنشاء إستثناء جديد

  1. يجب إنشاء كلاس جديد يرث من الكلاس Exception.

  2. يجب إستدعاء الكونستركتور الـ Superclass ( أي الكونستركتور الخاص بالكلاس Exception ) في كونستركتور الكلاس الجديد الذي نقوم بإنشائه.

  3. يجب تمرير الرسالة التي سيرميها الإستثناء في الدالة super().


مثال

هنا قمنا بتعريف كلاس جديد يمثل Exception و قمنا بتسميته MyException.

MyException.java
	  public class MyException extends Exception {

	  public MyException(String msg){
	  super(msg);
	  }

	  }
	

هنا قمنا بإنشاء الكلاس Main لتجربة الكلاس MyException.

Main.java
	  public class Main {

	  public static void main(String[] args) {

	  // لأنها قد ترمي إستثناء try و وضعناها بداخل الجملة argument و أعطيناها القيمة 0 كـ checkAge() هنا قمنا باستدعاء الدالة
	  try {
	  checkAge(20);
	  checkAge(18);
	  checkAge(10);
	  }
	  // ثم تقوم بعرض رسالة الخطأ e ثم تقوم بتخزينه في الكائن MyException تلتقط إستثناء نوعه catch هذه الـ
	  catch( MyException e ) {
	  System.out.println( e.getMessage() );
	  }

	  }


	  // أصغر من 13 argument إذا كان العمر الموضوع فيها كـ MyException هذه الدالة تقوم برمي إستثناء نوعه
	  public static void checkAge(int age) throws MyException {
	  if(age < 13) {
	  throw new MyException("you can't watch horror movies");
	  }
	  else {
	  System.out.println( "you can watch the movie" );
	  }
	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

	  you can watch the movie
	  you can watch the movie
	  you can't watch horror movies
	

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

غالباً ما تحتاج البرامج إلى تبادل البيانات مع مصادر خارجية, سواء كان ذلك لإستقبال البيانات من مصدر ما أو لإرسال البيانات إلى مستقبل ما.

المرسل و المستقبل في عملية تبادل البيانات قد تكون لهم أشكال مختلفة أمثلة:
يمكن تبادل البيانات بين البرنامج و الملف, أو بين البرنامج و الشبكة, أو بين البرنامج و قاعدة بيانات, أو بين البرنامج و برنامج إلخ...

و بالنسبة لأنواع البيانات التي يمكن نقلها. يمكنك تبادل أي نوع من أنواع البيانات أمثلة:
نصوص, صور, ملفات صوتية, برامج, إلخ..

لغة جافا توفر لك الحزمة java.io و التي تحتوي على جميع الكلاسات التي تحتاجها للتعامل مع الملفات, سواء لإدخال بيانات جديدة في الملف Input Operation أو لإستخراج بيانات موجودة في الملف Output Operation, و حتى لإنشاء أو حذف الملفات. و من هنا جاء الإسم I/O.

عملية إدخال البيانات أو إستخراجها من الملفات تسمى Streaming data, و هذه الكلمة تعني تدفق البيانات في اللغة العربية.

سميت هذه العملية ( تدفق البيانات ) لأنك عندما تتعامل مع الملفات سواء للقراءة أو الكتابة فأنت تقوم بذلك على دفعات صغيرة, بمعنى أنك تبرمج على سبيل المثال برنامج يفتح ملف معين و يقرأ منه حرف واحد أو مجموعة أحرف في كل دفعة حتى نقل كامل بيانات الملف. سترى ذلك لاحقاً بتفصيل.

Streams

الكلمة Streams تعني سلسلة من البيانات, يتم إستخراجها أو إدخالها في ملف معين.

هناك نوعين من الـ Streams و هما: input stream و output stream.


لذلك تم بناء الكلاسات التالية للتعامل مع الـ Streams:

  • الكلاس InputStream يستخدم لقراءة البيانات من ملف معين يسمى Source.

  • الكلاس OutputStream يستخدم لكتابة البيانات في ملف معين يسمى Destination.




في هذا الدرس سنشرح لك كيف تستخدم الحزمة I/O لقراءة أي نوع من الملفات و سنشرح فقط الكلاسات الأكثر استخداماً فيها.

طريقة التعامل مع الملفات

عندما تتعامل مع الملفات عليك إتباع نمط معين حتى تتجنب حدوث أي خطأ في البرنامج, و لقد قمنا بوضع خطوات ستساعدك كثيراً في فهم عملية نقل البيانات, و وضعنا أيضاً بعض الملاحظات التي يجب عليك الإنتباه لها أثناء تحديد مكان وجود الملفات التي سيتعامل البرنامج معها.


الخطوات التي يجب إتباعها لقراءة البيانات من ملف و كتابتها في ملف آخر

  1. إنشاء كائن يمثل الملف الذي تريد قراءة البيانات منه.

  2. إنشاء كائن يمثل الملف الذي تريد كتابة البيانات فيه.

  3. عليك وضع جميع الأوامر التي تتعامل مع الملفات بداخل الجملة try لأن البرنامج قد يتعرض لعدة مشاكل عندما يتعامل مع الملفات و التي سنذكرها لك لاحقاً.

  4. تحديد مسار و إسم و نوع الملف للكائن الذي يمثل الملف الذي سيتم قراءة البيانات منه.

  5. تحديد مسار و إسم و نوع الملف للكائن الذي يمثل الملف الذي سيتم كتابة البيانات فيه.

  6. تعريف متغير من النوع int.

  7. إستخدام حلقة بشكل متوازي بين الملفين, أي في كل دورة من دورات هذه الحلقة نقرأ حرف من الملف الأول و نضعه في الملف الثاني.

  8. إستخدام الدالة read() لقراءة حرف من الملف الأول, بعدها يجب تخزين هذا الحرف في المتغير.

  9. إستخدام الدالة write() لكتابة الحرف الموجود في المتغير في الملف الثاني.

  10. في الأخير عليك التأكد من إغلاق الملفات التي حاولت الإتصال معها سواء نجحت عملية النسخ أم لم تنجح, لذلك عليك إستدعاء الدالة close() في الجملة finally لإغلاق أي كائن متصل بالملفات حتى لا تعرض الملفات لأي خطر.


هذه الصورة توضح لك كيف تتم عملية نقل المحتوى من ملف لآخر, و هذا السيناريو هو نفسه تقريباً في جميع عمليات نقل البيانات و هو يستمر في نقل الأحرف الواحد تلو الآخر حتى آخر حرف موجود في الملف عندما نكتبه بالشكل الصحيح بداخل حلقة.

الدالة read() كما هو موضح في الصورة تقرأ حرف واحد من الملف و ترجعه كلما تم إستدعائها.
في حال تم قراءة جميع الأحرف الموجودة في الملف, ثم حاولت الدالة read() قرائة حرف من جديد, ستقوم بإرجاع 1-.
إذاً عندما ترجع الدالة read() القيمة 1- فهذا يعني أنه تم تخطي آخر حرف موجود في الملف.
من هنا جائت فكرة أنه يمكنك إستخدام الدالة read() و القيمة 1- كشرط أساسي لإيقاف عملية قرائة البيانات بعد آخر حرف يتم قرائته.


تحديد مسار الملفات التي تحاول التعامل معها

من الأشياء المهمة التي عليك الإنتباه لها عندما تتعامل مع الملفات هي معرفة كيف يتعامل نظام التشغيل الذي تبني برنامجك لأجله مع المسارات.

لنفترض أنه عندنا ملف موجود بداخل 3 مجلدات و نريد الوصول إليه كما في الصورة التالية:


الآن سترى كيف يتم تحديد المسار الموجود فيه الملف على أشهر أنظمة التشغيل.

  • على نظامي Mac و Windows نضع \\ بعد إسم كل مجلد عند تحديد المسار الموجود فيه الملف test.

  • على نظامي Unix و Linux نضع / بعد إسم كل مجلد عند تحديد المسار الموجود فيه الملف test.


لاحظ كيف أننا نضع نفس أسماء المجلدات و نفس إسم الملف لكي نصل للملف text. الإختلاف الوحيد هو الرمز الذي نضعه بعد كل مجلد.

A\\B\\C\\test.txt       // هكذا نصل للملف Mac و Windows على

	A/B/C/test.txt          // هكذا نصل للملف Linux و Unix على
  

في جافا يمكنك إستخدام الأسلوب الذي تريده مهما كان نظام التشغيل, ثم تقوم بتحويل المسار عنك ليتناسب مع نظام التشغيل.

Character Streams

الكلاسات التي تصنف كـ Character Streams مصممة للتعامل مع الملفات النصية العادية التي تعتمد على الترميز unicode, أي كل حرف في الملف يتم تمثيله بـ 2 Bytes.

هناك العديد من الكلاسات التي تنتمي للـ Character Streams لكن الكلاسات الأكثر إستخداماً هما : FileReader و FileWriter.


تقنياً

الكلاسات FileReader و FileWriter يعتمدون على الكلاسات FileInputStream و FileOutputStream.
الفرق الوحيد بينهم هو أن الكلاس FileReader يقرأ 2 Bytes في كل مرة و الكلاس FileWriter يكتب 2 Bytes في كل مرة.

الترميز unicode يمثل كل حرف موجود في الملف بـ 2 Bytes.
إذاً الكلاس FileReader يقرأ حرف من الملف في كل مرة و الكلاس FileWriter يكتب حرف في الملف في كل مرة.


مثال

في حال كان عندنا ملف إسمه input.txt موجود في المسار C:\\MyFiles\\ كما في الصورة التالية:

و نريد إنشاء نسخة ثانية منه في نفس المسار إسمها output.txt كما في الصورة التالية:

نكتب الكود التالي.

مثال

Main.java
import java.io.FileReader;
	  import java.io.FileWriter;
	  import java.io.IOException;

	  public class Main {

	  public static void main(String[] args) throws IOException {

	  FileReader in = null;
	  FileWriter out = null;

	  try {
	  in = new FileReader("C:\\MyFiles\\input.txt");
	  out = new FileWriter("C:\\MyFiles\\ouput.txt");
	  int c;

	  while ((c = in.read()) != -1) {
	  out.write(c);
	  }
	  }
	  catch(IOException e) {
	  System.out.println("There is IOException!");
	  }
	  finally {
	  if (in != null) {
	  in.close();
	  }
	  if (out != null) {
	  out.close();
	  }
	  }

	  }

	  }
	

شرح الكود


import java.io.FileReader;
		import java.io.FileWriter;
		import java.io.IOException;
	  
  • هنا قمنا باستدعاء الكلاسات التي سنحتاجها في البرنامج.


	public static void main(String[] args) throws IOException {
	  
  • هنا قمنا بوضع الجملة throws IOException لأن الدالة close() التي قمنا باستدعائها لاحقاً في الكود قد ترمي إستثناء في الدالة main().


        FileReader in = null;
		FileWriter out = null;
	  
  • هنا قمنا بإنشاء الكائن in لتمثيل الملف الذي سيتم فتحه لاحقاً.

  • و قمنا بإنشاء الكائن out لتمثيل الملف الذي سيتم خلقه لاحقاً.


            in = new FileReader("C:\\MyFiles\\input.txt");
		out = new FileWriter("C:\\MyFiles\\ouput.txt");
		int c;
	  
  • هنا قمنا بتحديد الملف الذي سيمثله الكائن in.
    الملف input.txt الموجود في المسار C:\\MyFiles\\ أصبح متمثلاً بالكائن in.

  • و قمنا بخلق ملف جديد على إسمه output.txt و يمثله الكائن out.
    الملف output.txt حتى الآن عبارة عن ملف فارغ موجود في المسار C:\\MyFiles\\.

  • المتغير c سنستخدمه كوسيط بين الملفين عند نقل البيانات.


            while ((c = in.read()) != -1) {
		out.write(c);
		}
	  
  • في الحلقة while سيحدث التالي في كل دورة:

    1. ستقوم الدالة read() بقراءة 2 Bytes من الملف الذي يمثله الكائن in ثم تخزنهم في المتغير c.

    2. إذا كانت قيمة المتغير c لا تساوي -1 , سيتم إدخال الـ 2 Bytes الموجودة في المتغير c في الكائن out بواسطة الدالة write().

الكلاسات المصممة للتعامل مع الـ Character Streams

في جافا تم بناء الكلاسات التي تتعامل مع الـ Character Streams بشكل متناسق كما في الصورة التالية.

الكلاس Reader هو الكلاس الأساسي لقراءة الأحرف من الملفات. و الكلاس Writer هو الكلاس الأساسي لكتابة الأحرف في الملفات.

أهم كلاسَين للتعامل مع الـ Character Streams هما الكلاس BufferedReader و الكلاس BufferedWriter بحيث يوفران لك كثير من الدوال التي تمكنك من التعامل مع الملفات بسهولة و مرونة و استخدام الـ buffer للحصول على أفضل أداء ممكن.


طريقة التعامل مع هذه الكلاسات

عندما تستخدم هذه الكلاسات ستستخدم مبدأ يسمى Upcasting.
و المقصود من هذا أنك مثلاً تنشئ كائن من الكلاس InputStream ثم تضع فيه أي كائن من الكلاسات التي ترث منه, مثل InputStreamReader.
بمعنى آخر تنشئ كائن من الكلاس InputStream ثم تحدد أنك تريد إستخدام الكلاس FileInputStream.


فكرة الـ Buffer و أهميتها عند التعامل مع الملفات

إفترض أن برنامجك سيقرأ على سبيل المثال ملف حجمه 10 MB, و التي تساوي 10,485,760 Bytes.

هل ستستدعي الدالة read() أكثر من 10 ملايين مرة حتى تقرأ هذا الملف؟!
حتماً لا لأنك إن فعلت ذلك ستهلك المعالج و الذاكرة و القرص الصلب لقراءة هذا الملف البسيط, و من هنا جائت فكرة الـ Buffer.


مفهوم الـ Buffer

الـ Buffer عبارة عن مساحة مؤقتة للتخزين يتم إنشاءها في الذاكرة من أجل قراءة كمية كبيرة من المعلومات, ثم يتم التخلص منها عند الإنتهاء.
عندما تستخدم كائن يتعامل مع الـ Buffer فهذا الكائن سينشئ هذه المساحة المؤقت في الذاكرة.

الآن إذا رجعنا للمثال السابق, كان يمكنك قراءة 1000 Bytes أو أكثر على سبيلا المثال في كل مرة تستدعي فيها الدالة read() بدل إستدعاءها لقراءة 1 Byte في كل مرة. و لو كان هذا مثال حي للاحظت الفارق في السرعة بين الأسلوبين.


في الجدول التالي وضعنا بعض كلاسات الـ Character Streams التي تستخدم للقراءة من الملفات.

الكلاس مع تعريفه
class InputStreamReader الكلاس InputStreamReader يقرأ بيانات الملف كـ bytes و يحولهم لأحرف حسب الترميز الذي نقوم بتحديده في الكونستركتور.
تابع القراءة »
class FileReader الكلاس FileReader يرث من الكلاسات InputStreamReader و Reader و هو يستخدم لقراءة Streams من الأحرف.
تابع القراءة »
class BufferedReader الكلاس BufferedReader يقرأ أحرف كائن الـ InputStreamReader و يضعهم في الـ buffer. و هذا يوفر لك طرق عديدة لقراءة المحتوى من الـ buffer. مثل قراءته حرفاً حرفاً, أو تخزينه في مصفوفة, أو قراءته سطراً سطراً.
يمكنك تحديد حجم الـ buffer, أو استخدام الحجم الإفتراضي لها و الذي يعتبر جيداً في معظم الحالات.
تابع القراءة »

في الجدول التالي وضعنا بعض كلاسات الـ Character Streams التي تستخدم للكتابة في الملفات.

الكلاس مع تعريفه
class OutputStreamWriter الكلاس OutputStreamWriter يكتب الأحرف في الملف كـ bytes حسب الترميز الذي نقوم بتحديده في الكونستركتور.
تابع القراءة »
class FileWriter الكلاس FileWriter يرث من الكلاسات OutputStreamWriter و Writer و هو يستخدم لكتابة نص في الملف.
تابع القراءة »
class BufferedWriter الكلاس BufferedWriter يضع أحرف كائن الـ OutputStreamWirter في الـ buffer. و هذا يوفر لك طرق عديدة لكتابة محتوى الـ buffer في الملف. مثل كتابته حرفاً حرفاً, أو تخزينه في مصفوفة, أو كتابته سطراً سطراً.
يمكنك تحديد حجم الـ buffer, أو استخدام الحجم الإفتراضي لها و الذي يعتبر جيداً في معظم الحالات.
تابع القراءة »

Byte Streams

الكلاسات التي تصنف كـ Byte Streams مصممة للتعامل الملفات الغير نصية التي تخزن المحتوى بشكل سلسلة بيانات من 1 Byte مثل ( PNG, MP4, MP3.. ) و يمكنها نقل الأحرف العادية شرط أن تكون الأحرف المستخدمة تتألف من 1 Byte حتى تنقل بشكل صحيح.

هناك العديد من الكلاسات التي تنتمي للـ Byte Streams لكن الكلاسات الأكثر إستخداماً هما : FileInputStream و FileOutputStream.


مثال

في حال كان عندنا ملف إسمه input.MP4 موجود في المسار C:\\MyFiles\\ كما في الصورة التالية:

و نريد إنشاء نسخة ثانية منه في نفس المسار إسمها output.MP4 كما في الصورة التالية:

نكتب الكود التالي.

مثال

Main.java
import java.io.FileInputStream;
	  import java.io.FileOutputStream;
	  import java.io.IOException;

	  public class Main {

	  public static void main(String[] args) throws IOException {

	  FileInputStream in = null;
	  FileOutputStream out = null;

	  try {
	  in = new FileInputStream("C:\\MyFiles\\input.MP4");
	  out = new FileOutputStream("C:\\MyFiles\\ouput.MP4");
	  int c;

	  while ((c = in.read()) != -1) {
	  out.write(c);
	  }
	  }
	  catch(IOException e) {
	  System.out.println("There is IOException!");
	  }
	  finally {
	  if (in != null) {
	  in.close();
	  }
	  if (out != null) {
	  out.close();
	  }
	  }

	  }

	  }
	

شرح الكود


import java.io.FileInputStream;
		import java.io.FileOutputStream;
		import java.io.IOException;
	  
  • هنا قمنا باستدعاء الكلاسات التي سنحتاجها في البرنامج.


    public static void main(String[] args) throws IOException {
	  
  • هنا قمنا بوضع الجملة throws IOException لأن الدالة close() التي قمنا باستدعائها لاحقاً في الكود قد ترمي إستثناء في الدالة main().


        FileInputStream in = null;
		FileOutputStream out = null;
	  
  • هنا قمنا بإنشاء الكائن in لتمثيل الملف الذي سيتم فتحه لاحقاً.

  • و قمنا بإنشاء الكائن out لتمثيل الملف الذي سيتم خلقه لاحقاً.


            in = new FileInputStream("C:\\MyFiles\\input.MP4");
		out = new FileOutputStream("C:\\MyFiles\\ouput.MP4");
		int c;
	  
  • هنا قمنا بتحديد الملف الذي سيمثله الكائن in.
    الملف input.mp4 الموجود في المسار C:\\MyFiles\\ أصبح متمثلاً بالكائن in.

  • و قمنا بخلق ملف جديد على إسمه output.MP4 و يمثله الكائن out.
    الملف output.MP4 حتى الآن عبارة عن ملف فارغ موجود في المسار C:\\MyFiles\\.

  • المتغير c سنستخدمه كوسيط بين الملفين عند نقل البيانات.


            while ((c = in.read()) != -1) {
		out.write(c);
		}
	  
  • في الحلقة while سيحدث التالي في كل دورة:

    1. ستقوم الدالة read() بقراءة 1 Byte من الملف الذي يمثله الكائن in ثم تخزنهم في المتغير c.

    2. إذا كانت قيمة المتغير c لا تساوي -1 , سيتم إدخال الـ 1 Byte الموجودة في المتغير c في الكائن out بواسطة الدالة write().


ملاحظة

عندما تقوم بتشغيل هذا البرنامج. سيحتاج إلى بعض الوقت حتى ينتهي من عملية النسخ بشكل كامل (أي لا تظنه معلق), و في حال قمت بإيقاف البرنامج أثناء عمله, إفتح الملف Output.MP4 و ستجد أن الجزء الأخير في الفيديو مفقود.

الكلاسات المصممة للتعامل مع الـ Byte Streams

في جافا تم بناء الكلاسات التي تتعامل مع الـ Byte Streams بشكل متناسق كما في الصورة التالية.


الكلاس InputStream هو الكلاس الأساسي لقراءة البيانات من ملف. و الكلاس OutputStream هو الكلاس الأساسي لكتابة البيانات في ملف.

أهم كلاسَين للتعامل مع الـ Streams هما الكلاس FileInputStream و الكلاس FileOutputStream بحيث يوفران لك كثير من الدوال التي تمكنك من التعامل مع الملفات بسهولة و مرونة.


في الجدول التالي وضعنا بعض كلاسات الـ Byte Streams التي تستخدم للكتابة في الملفات.

الكلاس مع تعريفه
class FileInputStream الكلاس FileInputStream يستخدم لقراءة البيانات من الملفات.
تابع القراءة »
class ByteArrayInputStream الكلاس ByteArrayInputStream يسمح باستخدام الـ buffer في الذاكرة كـ InputStream. و هو يقرأ البيانات من المصدر كمصفوفة نوعها byte.
تابع القراءة »
class DataInputStream الكلاس DataInputStream يستخدم لقراءة البيانات البدائية primitive data types من ملف معين.
تابع القراءة »


في الجدول التالي وضعنا بعض كلاسات الـ Byte Streams التي تستخدم للقراءة من الملفات.

الكلاس مع تعريفه
class FileOutputStream

الكلاس FileOutputStream يستخدم لإنشاء ملف جديد و كتابة البيانات فيه.
في حال وجود ملف يحمل نفس الإسم و النوع في نفس المسار الموضوع للـ OutputStream, سيتم تبديل الملف القديم بملف الـ OutputStreamالجديد.
تابع القراءة »

class ByteArrayOutputStream الكلاس ByteArrayOutputStream ينشئ buffer في الذاكرة لتخزين بيانات الـ Stream فيها قبل إرسالها للـ OutputStream.
تابع القراءة »
class DataOutputStream الكلاس DataOutputStream يستخدم لكتابة البيانات البدائية primitive data types في ملف معين.
تابع القراءة »

الكلاس File

تم إعداد الكلاس File لمعالجة الملفات و المجلدات.
لا يوجد كلاس خاص لمعالجة المجلدات لأن المجلدات عبارة عن ملفات فارغة يمكنها إحتواء ملفات و مجلدات أخرى.


يستخدم الكلاس File للأغراض التالية:

  • لخلق ملف أو مجلد جديد.

  • لحذف ملف أو مجلد موجود.

  • للبحث عن ملف أو مجلد.

  • لعرض جميع الملفات و المجلدات الموجودة في المجلد.

  • لقراءة صلاحيات الملف أو المجلد.

  • لتغيير صلاحيات الملف أو المجلد.


وضعنا لك هنا أهم المعلومات التي قد تحتاجها حول الكلاس File.

تابع القراءة »

التعامل مع المجلدات في جافا

المجلد يسمى directory في البرمجة, و هو عبارة عن ملف يمكنه تخزين ملفات و مجلدات أخرى.

باستخدام كائن من الكلاس File يمكنك إنشاء العدد الذي تريده من المجلدات, و معرفة عدد الملفات الموجودة في مجلد ما.
لتعرف تفاصيل أكثر عن علاقة الكلاس File بالمجلدات, أدرس الكلاس File و ستتعرف على بعض الدوال الموجودة فيه المخصصة للتعامل مع المجلدات.


إنشاء المجلدات في جافا

يوجد دالتين في الكلاس File يمكن إستخدامها لإنشاء مجلدات.

  • الدالة mkdir() تستخدم لإنشاء مجلد واحد, و ترجع true إذا تم إنشاءه بنجاح و false إذا لم فشلة عملية إنشاءه.
    إذا فشلت علية إنشاءه فذلك يعني أن المسار الموضوع في كائن الـ File موجود في الأصل, أو أنه لا يمكن إنشاء المجلد لإن المسار الموضوع قبل إسم الملف الذي سيتم إنشائه غير موجود.

  • الدالة mkdirs() تستخدم لإنشاء مجلد أو أكثر.
    هنا في حال كان المسار الموضوع غير موجود ستقوم هي بإنشاءه. أي ستنشئ جميع المجلدات الموضوعة في المسار.



عرض محتوى المجلدات في جافا

يمكنك استخدام الدالة list() الموجودة في الكلاس File لعرض جميع الملفات الموجودة في المجلد.


مثال

في هذا المثال سنقوم بإنشاء مجلد إسمه harmash بداخله سننشئ مجلدين images و videos, و سننشئ فيه أيضاً ملف إسمه index.php.

بعدها سنقوم بعرض جميع الأشياء الموجودة في المجلد harmash.

Main.java
import java.io.File;
	  import java.io.IOException;

	  public class Main {

	  public static void main(String[] args) throws IOException {

	  try {
	  // harmash قمنا بإنشاء هذا المتغير للإشارة إلى المسار الأساسي الذي سيوضع فيه المجلد
	  String websitePath = "C:\\projects\\harmash\\";

	  File harmashFolder = new File(websitePath);                 // الذي سننشئه لاحقاً harmash هنا قمنا بإنشاء كائن يشير لمسار المشروع
	  File imagesFolder  = new File(websitePath + "images");      // harmash الذي سننشئه لاحقاً بداخل المجلد images هنا قمنا بإنشاء كائن يشير للمجلد
	  File videosFolder  = new File(websitePath + "videos");      // harmash الذي سننشئه لاحقاً بداخل المجلد videos هنا قمنا بإنشاء كائن يشير للمجلد
	  File pageFile      = new File(websitePath + "index.php");   // harmash الذي سننشئه لاحقاً بداخل المجلد index.php هنا قمنا بإنشاء كائن يشير للملف

	  harmashFolder.mkdirs();      // harmash و بداخله المجلد project هنا قمنا بإنشاء المجلد
	  imagesFolder.mkdir();        // videos هنا قمنا بإنشاء المجلد
	  videosFolder.mkdir();        // images هنا قمنا بإنشاء المجلد
	  pageFile.createNewFile();    // index.php هنا قمنا بإنشاء الملف

	  System.out.println("c:\\projects\\harmash contain: ");

	  // هنا قمنا بعرض جميع المجلدات و الملفات الموجودة في المشروع
	  String[] paths = harmashFolder.list();

	  for (String path:paths) {
	  System.out.println("- " + path);
	  }
	  }
	  catch(Exception e) {
	  System.out.println("There is Exception!");
	  }

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

c:\projects\harmash contain:
	  - images
	  - index.php
	  - videos 
	

الكلاس InputStreamReader في جافا

الكلاس InputStreamReader يقرأ بيانات الملف كـ bytes و يحولهم لأحرف حسب الترميز الذي نقوم بتحديده في الكونستركتور.


الكلاس InputStreamReader يحتوي على الـ constructors المذكورين في الجدول التالي.

الكونستركتور مع تعريفه
public InputStreamReader(InputStream in) ينشئ كائن نوعه InputStreamReader يستخدم الترميز الإفتراضي.
public InputStreamReader(InputStream in, Charset cs) ينشئ كائن نوعه InputStreamReader يستخدم ترميز كائن الـ Charset
public InputStreamReader(InputStream in, CharsetDecoder dec) ينشئ كائن نوعه InputStreamReader يستخدم ترميز كائن الـ CharsetDecoder
public InputStreamReader(InputStream in, String charsetName) ينشئ كائن نوعه InputStreamReader يستخدم ترميز كائن الـ String


بعد أن يصبح كائن الـ InputStreamReader جاهزاً, يمكنك إستخدام الكثير من الدوال الجاهزة للقراءة من الملف أو لفعل أي شيء آخر.

الدالة مع تعريفها
public void close() throws IOException تغلق الـ InputStreamReader و تقطع الإتصال بين الـ Stream و أي مصدر كان متصلاً فيه.
public String getEncoding() ترجع إسم الترميز المستخدم من قبل كائن الـ InputStreamReader.
public int read() throws IOException في كل مرة تقرأ حرف جديد من أحرف الـ InputStreamReader و ترجعه.
ترجع 1- إذا وصلت لنهاية الملف.
public int read(char[] cbuf, int offset, int length) throws IOException في كل مرة تستدعى فيها تقرأ مجموعة أحرف جديدة من الـ InputStreamReader و تخزنهم في المصفوفة cbuf.
المتغير offset يقصد به من أي عنصر في المصفوفة cbuf سيكتب في الـ InputStreamReader.
المتغير length يقصد به كم عنصر من عناصر المصفوفة cbuf سيكتب في الـ InputStreamReader.


مثال

في هذا المثال سنقوم بإنشاء ملف جديد و كتابة نص صغير فيه, ثم سنقوم بقراءة النص من الملف.

Main.java
                    import java.io.FileInputStream;
	  import java.io.FileOutputStream;
	  import java.io.InputStreamReader;
	  import java.io.OutputStreamWriter;
	  import java.io.IOException;

	  public class Main {

	  public static void main(String[] args) {

	  try {
	  // يشير إلى الملف الذي سنكتب البيانات فيه و في حال لم يكن موجوداً, سيتم إنشاءه FileOutputStream هنا قمنا بإنشاء كائن نوعه
	  FileOutputStream fos = new FileOutputStream("c:\\MyFiles\\test.txt");

	  // للكتابة في الملف OutputStreamWriter هنا قمنا بإنشاء كائن نوعه
	  OutputStreamWriter osw = new OutputStreamWriter( fos, "UTF-16" );

	  // هنا قمنا بكتابة نص في الملف ثم قمنا بتفريغ الذاكرة و إغلاق الكائن المتصل بالملف
	  osw.write("الترميز" + " UTF-16 " + "يجعلك تخزن البيانات في جميع لغات العالم");
	  osw.flush();
	  osw.close();

	  // يشير إلى الملف الذي ستقرأ البيانات منه FileInputStream هنا قمنا بإنشاء كائن نوعه
	  FileInputStream fis = new FileInputStream("c:\\MyFiles\\test.txt");

	  // للقراءة من الملف InputStreamReader هنا قمنا بإنشاء كائن نوعه
	  InputStreamReader isr = new InputStreamReader( fis, "UTF-16" );

	  // هنا قمنا بإنشاء حلقة تمر على جميع أحرف الملف, في كل دورة تقرأ حرف من الملف ثم تعرضه و بعدها قمنا بإغلاق الكائن المتصل بالملف
	  int c;
	  while ((c = isr.read()) != -1) {
	  System.out.print((char)c);
	  }
	  isr.close();
	  }
	  catch(IOException e) {
	  System.out.println("There is IOException!");
	  }

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

الترميز UTF-16 يجعلك تخزن البيانات في جميع لغات العالم

الكلاس FileReader في جافا

الكلاس FileReader يرث من الكلاسات InputStreamReader و Reader و هو يستخدم لقراءة Streams من الأحرف.


الكلاس FileReader يحتوي على الـ constructors المذكورين في الجدول التالي.

الكونستركتور مع تعريفه
public FileReader(File file) ينشئ كائن نوعه FileReader يستخدم للقراءة من كائن الـ File.
public FileReader(String fileName) ينشئ كائن نوعه FileReader يستخدم للقراءة من الملف الذي يشير إليه كائن الـ String.
public FileReader(FileDescriptor fd) ينشئ كائن نوعه FileReader يستخدم للقراءة من كائن الـ FileDescriptor.


بما أن الكلاس FileReader يرث من الكلاسات InputStreamReader و Reader, يمكنك إستدعاء الدوال التي سيرثها هذا الكائن من هذه الكلاسات.

مثال

في هذا المثال سنقوم بإنشاء ملف جديد و كتابة نص صغير فيه, ثم سنقوم بقراءة النص من الملف.

Main.java
                    import java.io.FileReader;
	  import java.io.FileWriter;
	  import java.io.IOException;

	  public class Main {

	  public static void main(String[] args) {

	  try {
	  // لإنشاء ملف و الكتابة فيه لاحقاً FileWriter هنا قمنا بإنشاء كائن نوعه
	  FileWriter fw = new FileWriter("c:\\MyFiles\\test.txt");

	  // هنا قمنا بكتابة نص في الملف ثم قمنا بتفريغ الذاكرة و إغلاق الكائن المتصل بالملف
	  fw.write("first line.\nsecond line.\nthird line.");
	  fw.flush();
	  fw.close();

	  // يسمح بالقراءة من الملف fr يشير إلى الملف, إذا الكائن FileReader هنا قمنا بإنشاء كائن نوعه
	  FileReader fr = new FileReader("c:\\MyFiles\\test.txt");

	  // هنا قمنا بإنشاء حلقة تمر على جميع أحرف الملف, في كل دورة تقرأ حرف من الملف ثم تعرضه و بعدها قمنا بإغلاق الكائن المتصل بالملف
	  int c;
	  while ((c = fr.read()) != -1) {
	  System.out.print((char)c);
	  }
	  fr.close();
	  }
	  catch(IOException e) {
	  System.out.println("There is IOException!");
	  }

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

                    first line.
	  second line.
	  third line. 
	

الكلاس BufferedReader في جافا

الكلاس BufferedReader يقرأ أحرف كائن الـ InputStreamReader و يضعهم في الـ buffer. و هذا يوفر لك طرق عديدة لقراءة المحتوى من الـ buffer. مثل قراءته حرفاً حرفاً, أو تخزينه في مصفوفة, أو قراءته سطراً سطراً.

يمكنك تحديد حجم الـ buffer, أو استخدام الحجم الإفتراضي لها و الذي يعتبر جيداً في معظم الحالات.


الكلاس BufferedReader يحتوي على الـ constructors المذكورين في الجدول التالي.

الكونستركتور مع تعريفه
BufferedReader(Reader in) ينشئ كائن نوعه BufferedReader يستخدم حجم الـ buffer الإفتراضي.
BufferedReader(Reader in, int size) ينشئ كائن نوعه BufferedReader يستخدم حجم الـ buffer الذي نقوم بتحديده.


بعد أن يصبح كائن الـ BufferedReader جاهزاً, يمكنك إستخدام الكثير من الدوال الجاهزة للقراءة من الملف أو لفعل أي شيء آخر.

الدالة مع تعريفها
public void close() throws IOException تغلق الـ BufferedReader و تقطع الإتصال بين الـ Stream و أي مصدر كان متصلاً فيه.
public int read() throws IOException في كل مرة تقرأ حرف جديد من أحرف الـ BufferedReader و ترجعه.
ترجع 1- إذا وصلت لنهاية الملف.
public int read(char[] cbuf, int offset, int length) throws IOException في كل مرة تستدعى فيها تقرأ مجموعة أحرف جديدة من الـ BufferedReader و تخزنهم في المصفوفة cbuf.
المتغير offset يقصد به من أي عنصر في المصفوفة cbuf سيكتب في الـ BufferedReader.
المتغير length يقصد به كم عنصر من عناصر المصفوفة cbuf سيكتب في الـ BufferedReader.
public String readLine() throws IOException في كل مرة تقرأ سطر جديد من أسطر الـ BufferedReader و ترجعه.
ترجع null إذا وصلت لنهاية الملف.
السطر يتعبر منتهياً إذا كان ينتهي بـ \n, أو بـ \r, أو بالإثنين مع بعض \n\r.
public long skip(long n) throws IOException تتخطى عدد من الأحرف الموجودة في الـ buffer. ثم ترجع عدد الأحرف التي تجاوزتها.
المتغير N يقصد به عدد الأحرف التي سيتم تجاوزها عند القراءة من الـ buffer.


مثال

في هذا المثال سنقوم بإنشاء ملف جديد و كتابة نص صغير فيه, ثم سنقوم بقراءة النص من الملف.

Main.java
                    import java.io.BufferedReader;
	  import java.io.BufferedWriter;
	  import java.io.FileInputStream;
	  import java.io.FileOutputStream;
	  import java.io.InputStreamReader;
	  import java.io.OutputStreamWriter;
	  import java.io.IOException;

	  public class Main {

	  public static void main(String[] args) {

	  try {
	  // يشير إلى الملف الذي سنكتب البيانات فيه و في حال لم يكن موجوداً, سيتم إنشاءه FileOutputStream هنا قمنا بإنشاء كائن نوعه
	  FileOutputStream fos = new FileOutputStream("c:\\MyFiles\\test.txt");

	  // BufferedWriter من أجل كائن الـ buffer لوضعه في الـ OutputStreamWriter هنا قمنا بإنشاء كائن نوعه
	  OutputStreamWriter osw = new OutputStreamWriter( fos, "UTF-16" );

	  // للكتابة في الملف BufferedWriter هنا قمنا بإنشاء كائن نوعه
	  BufferedWriter bw = new BufferedWriter(osw);

	  // هنا قمنا بكتابة نص في الملف ثم قمنا بتفريغ الذاكرة و إغلاق الكائن المتصل بالملف
	  bw.write("السطر الأول");
	  bw.newLine();
	  bw.write("السطر الثاني");
	  bw.flush();
	  bw.close();

	  // يشير إلى الملف الذي ستقرأ البيانات منه FileInputStream هنا قمنا بإنشاء كائن نوعه
	  FileInputStream fis = new FileInputStream("c:\\MyFiles\\test.txt");

	  // BufferedReader من أجل كائن الـ buffer لوضعه في الـ InputStreamReader هنا قمنا بإنشاء كائن نوعه
	  InputStreamReader isr = new InputStreamReader( fis, "UTF-16" );

	  // للقراءة من الملف BufferedReader هنا قمنا بإنشاء كائن نوعه
	  BufferedReader br = new BufferedReader(isr);

	  // هنا قمنا بإنشاء حلقة تمر على جميع أحرف الملف, في كل دورة تقرأ حرف من الملف ثم تعرضه و بعدها قمنا بإغلاق الكائن المتصل بالملف
	  int c;
	  while ((c = br.read()) != -1) {
	  System.out.print((char)c);
	  }
	  br.close();
	  }
	  catch(IOException e) {
	  System.out.println("There is IOException!");
	  }

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

                    السطر الأول
	  السطر الثاني
	

الكلاس OutputStreamWriter في جافا

الكلاس OutputStreamWriter يكتب الأحرف في الملف كـ bytes حسب الترميز الذي نقوم بتحديده في الكونستركتور.


الكلاس OutputStreamWriter يحتوي على الـ constructors المذكورين في الجدول التالي.

الكونستركتور مع تعريفه
public OutputStreamWriter(OutputStream out) ينشئ كائن نوعه OutputStreamWriter يستخدم الترميز الإفتراضي.
public OutputStreamWriter(OutputStream out, Charset cs) ينشئ كائن نوعه OutputStreamWriter يستخدم ترميز كائن الـ Charset.
public OutputStreamWriter(OutputStream out, CharsetEncoder enc) ينشئ كائن نوعه OutputStreamWriter يستخدم ترميز كائن الـ CharsetEncoder.
public OutputStreamWriter(OutputStream out, String charsetName) ينشئ كائن نوعه OutputStreamWriter يستخدم ترميز كائن الـ String.


بعد أن يصبح كائن الـ OutputStreamWriter جاهزاً, يمكنك إستخدام الكثير من الدوال الجاهزة للكتابة في الملف أو لفعل أي شيء آخر.

الدالة مع تعريفها
public void close() throws IOException تغلق الـ OutputStreamWriter و تقطع الإتصال بين الـ Stream و أي مصدر كان متصلاً فيه.
public void flush() throws IOException تضمن عدم بقاء أي بيانات في الذاكرة, و ترسل أي بيانات موجودة في الـ buffer إلى كائن الـ OutputStreamWriter.
تستدعى دائماً قبل استدعاء الدالة close().
public String getEncoding() ترجع إسم الترميز المستخدم من قبل كائن الـ OutputStreamWriter.
public void write(int c) throws IOException تكتب الحرف الذي يعطى لها كـ argument في كائن الـ OutputStream.
public void write(char[] cbuf, int off, int len) throws IOException في كل مرة تستدعى فيها تكتب مجموعة أحرف من المصفوفة cbuf في كائن الـ OutputStream.
المتغير off يقصد به من أي عنصر في المصفوفة cbuf سيكتب في كائن الـ OutputStream.
المتغير len يقصد به كم عنصر من عناصر المصفوفة cbuf سيكتب في كائن الـ OutputStream.
public void write(String[] str, int off, int len) throws IOException في كل مرة تستدعى فيها تكتب مجموعة أحرف من النص str في كائن الـ OutputStream.
المتغير off يقصد به من أي حرف في النص str سيكتب في كائن الـ OutputStream.
المتغير len يقصد به كم حرف من أحرف النص str سيكتب في كائن الـ OutputStream.


مثال

في هذا المثال سنقوم بإنشاء ملف جديد و كتابة نص صغير فيه, ثم سنقوم بقراءة النص من الملف.

Main.java
                    import java.io.FileInputStream;
	  import java.io.FileOutputStream;
	  import java.io.InputStreamReader;
	  import java.io.OutputStreamWriter;
	  import java.io.IOException;

	  public class Main {

	  public static void main(String[] args) {

	  try {
	  // يشير إلى الملف الذي سنكتب البيانات فيه و في حال لم يكن موجوداً, سيتم إنشاءه FileOutputStream هنا قمنا بإنشاء كائن نوعه
	  FileOutputStream fos = new FileOutputStream("c:\\MyFiles\\test.txt");

	  // للكتابة في الملف OutputStreamWriter هنا قمنا بإنشاء كائن نوعه
	  OutputStreamWriter osw = new OutputStreamWriter( fos, "UTF-16" );

	  // هنا قمنا بكتابة نص في الملف ثم قمنا بتفريغ الذاكرة و إغلاق الكائن المتصل بالملف
	  osw.write("الترميز" + " UTF-16 " + "يجعلك تخزن البيانات في جميع لغات العالم");
	  osw.flush();
	  osw.close();

	  // يشير إلى الملف الذي ستقرأ البيانات منه FileInputStream هنا قمنا بإنشاء كائن نوعه
	  FileInputStream fis = new FileInputStream("c:\\MyFiles\\test.txt");

	  // للقراءة من الملف InputStreamReader هنا قمنا بإنشاء كائن نوعه
	  InputStreamReader isr = new InputStreamReader( fis, "UTF-16" );

	  // هنا قمنا بإنشاء حلقة تمر على جميع أحرف الملف, في كل دورة تقرأ حرف من الملف ثم تعرضه و بعدها قمنا بإغلاق الكائن المتصل بالملف
	  int c;
	  while ((c = isr.read()) != -1) {
	  System.out.print((char)c);
	  }
	  isr.close();
	  }
	  catch(IOException e) {
	  System.out.println("There is IOException!");
	  }

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

الترميز UTF-16 يجعلك تخزن البيانات في جميع لغات العالم

الكلاس FileWriter في جافا

الكلاس FileWriter يرث من الكلاسات OutputStreamWriter و Writer و هو يستخدم لكتابة نص في الملف.


الكلاس FileWriter يحتوي على الـ constructors المذكورين في الجدول التالي.

الكونستركتور مع تعريفه
public FileWriter(File file) ينشئ كائن نوعه FileWriter يستخدم للكتابة في كائن الـ File.
public FileWriter(File file, boolean append) ينشئ كائن نوعه FileWriter يستخدم للكتابة في كائن الـ File.
في حال تم إعطاء true كقيمة للباراميتر append, سيضيف المحتوى الجديد في آخر المحتوى القديم.
في حال تم إعطاء false كقيمة للباراميتر append, سيمسح المحتوى القديم و يضيف المحتوى الجديد.
public FileWriter(String fileName) ينشئ كائن نوعه FileWriter يستخدم للكتابة في الملف الذي يشير إليه كائن الـ String.
public FileWriter(String fileName, boolean append) ينشئ كائن نوعه FileWriter يستخدم للكتابة في الملف الذي يشير إليه كائن الـ String.
في حال تم إعطاء true كقيمة للباراميتر append, سيضيف المحتوى الجديد في آخر المحتوى القديم.
في حال تم إعطاء false كقيمة للباراميتر append, سيمسح المحتوى القديم و يضيف المحتوى الجديد.
public FileWriter(FileDescriptor fd) ينشئ كائن نوعه FileWriter يستخدم للكتابة في كائن الـ FileDescriptor.


بما أن الكلاس FileWriter يرث من الكلاسات InputStreamWriter و Writer, يمكنك إستدعاء الدوال التي سيرثها هذا الكائن من هذه الكلاسات.

مثال

في هذا المثال سنقوم بإنشاء ملف جديد و كتابة نص صغير فيه, ثم سنقوم بقراءة النص من الملف.

Main.java
                    import java.io.FileReader;
	  import java.io.FileWriter;
	  import java.io.IOException;

	  public class Main {

	  public static void main(String[] args) {

	  try {
	  // لإنشاء ملف و الكتابة فيه لاحقاً FileWriter هنا قمنا بإنشاء كائن نوعه
	  FileWriter fw = new FileWriter("c:\\MyFiles\\test.txt");

	  // هنا قمنا بكتابة نص في الملف ثم قمنا بتفريغ الذاكرة و إغلاق الكائن المتصل بالملف
	  fw.write("first line.\nsecond line.\nthird line.");
	  fw.flush();
	  fw.close();

	  // يسمح بالقراءة من الملف fr يشير إلى الملف, إذا الكائن FileReader هنا قمنا بإنشاء كائن نوعه
	  FileReader fr = new FileReader("c:\\MyFiles\\test.txt");

	  // هنا قمنا بإنشاء حلقة تمر على جميع أحرف الملف, في كل دورة تقرأ حرف من الملف ثم تعرضه و بعدها قمنا بإغلاق الكائن المتصل بالملف
	  int c;
	  while ((c = fr.read()) != -1) {
	  System.out.print((char)c);
	  }
	  fr.close();
	  }
	  catch(IOException e) {
	  System.out.println("There is IOException!");
	  }

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

                    first line.
	  second line.
	  third line.
	

الكلاس BufferedWriter في جافا

الكلاس BufferedWriter يضع أحرف كائن الـ OutputStreamWirter في الـ buffer. و هذا يوفر لك طرق عديدة لكتابة محتوى الـ buffer في الملف. مثل كتابته حرفاً حرفاً, أو تخزينه في مصفوفة, أو كتابته سطراً سطراً.

يمكنك تحديد حجم الـ buffer, أو استخدام الحجم الإفتراضي لها و الذي يعتبر جيداً في معظم الحالات.


الكلاس BufferedWriter يحتوي على الـ constructors المذكورين في الجدول التالي.

الكونستركتور مع تعريفه
BufferedWriter(Writer out) ينشئ كائن نوعه BufferedWriter يستخدم حجم الـ buffer الإفتراضي.
BufferedWriter(Writer out, int size) ينشئ كائن نوعه BufferedWriter يستخدم حجم الـ buffer الذي نقوم بتحديده.


بعد أن يصبح كائن الـ BufferedWriter جاهزاً, يمكنك إستخدام الكثير من الدوال الجاهزة للكتابة في الملف أو لفعل أي شيء آخر.

الدالة مع تعريفها
public void close() throws IOException تغلق الـ BufferedWriter و تقطع الإتصال بين الـ Stream و أي مصدر كان متصلاً فيه.
public void flush() throws IOException تضمن عدم بقاء أي بيانات في الذاكرة, و ترسل أي بيانات موجودة في الـ buffer إلى كائن الـ BufferedWriter.
تستدعى دائماً قبل استدعاء الدالة close().
public void newLine() throws IOException تكتب أحرف تمثل نهاية للسطر.
public void write(int c) throws IOException تكتب الحرف الذي يعطى لها كـ argument في كائن الـ BufferedWriter.
public void write(char[] cbuf, int off, int len) throws IOException في كل مرة تستدعى فيها تكتب مجموعة أحرف من المصفوفة cbuf في كائن الـ BufferedWriter.
المتغير off يقصد به من أي عنصر في المصفوفة cbuf سيكتب في كائن الـ BufferedWriter.
المتغير len يقصد به كم عنصر من عناصر المصفوفة cbuf سيكتب في كائن الـ BufferedWriter.
public void write(String[] str, int off, int len) throws IOException في كل مرة تستدعى فيها تكتب مجموعة أحرف من النص str في كائن الـ BufferedWriter.
المتغير off يقصد به من أي حرف في النص str سيكتب في كائن الـ BufferedWriter.
المتغير len يقصد به كم حرف من أحرف النص str سيكتب في كائن الـ BufferedWriter.


مثال

في هذا المثال سنقوم بإنشاء ملف جديد و كتابة نص صغير فيه, ثم سنقوم بقراءة النص من الملف.

Main.java
                    import java.io.BufferedReader;
	  import java.io.BufferedWriter;
	  import java.io.FileInputStream;
	  import java.io.FileOutputStream;
	  import java.io.InputStreamReader;
	  import java.io.OutputStreamWriter;
	  import java.io.IOException;

	  public class Main {

	  public static void main(String[] args) {

	  try {
	  // يشير إلى الملف الذي سنكتب البيانات فيه و في حال لم يكن موجوداً, سيتم إنشاءه FileOutputStream هنا قمنا بإنشاء كائن نوعه
	  FileOutputStream fos = new FileOutputStream("c:\\MyFiles\\test.txt");

	  // BufferedWriter من أجل كائن الـ buffer لوضعه في الـ OutputStreamWriter هنا قمنا بإنشاء كائن نوعه
	  OutputStreamWriter osw = new OutputStreamWriter( fos, "UTF-16" );

	  // للكتابة في الملف BufferedWriter هنا قمنا بإنشاء كائن نوعه
	  BufferedWriter bw = new BufferedWriter(osw);

	  // هنا قمنا بكتابة نص في الملف ثم قمنا بتفريغ الذاكرة و إغلاق الكائن المتصل بالملف
	  bw.write("السطر الأول");
	  bw.newLine();
	  bw.write("السطر الثاني");
	  bw.flush();
	  bw.close();

	  // يشير إلى الملف الذي ستقرأ البيانات منه FileInputStream هنا قمنا بإنشاء كائن نوعه
	  FileInputStream fis = new FileInputStream("c:\\MyFiles\\test.txt");

	  // BufferedReader من أجل كائن الـ buffer لوضعه في الـ InputStreamReader هنا قمنا بإنشاء كائن نوعه
	  InputStreamReader isr = new InputStreamReader( fis, "UTF-16" );

	  // للقراءة من الملف BufferedReader هنا قمنا بإنشاء كائن نوعه
	  BufferedReader br = new BufferedReader(isr);

	  // هنا قمنا بإنشاء حلقة تمر على جميع أحرف الملف, في كل دورة تقرأ حرف من الملف ثم تعرضه و بعدها قمنا بإغلاق الكائن المتصل بالملف
	  int c;
	  while ((c = br.read()) != -1) {
	  System.out.print((char)c);
	  }
	  br.close();
	  }
	  catch(IOException e) {
	  System.out.println("There is IOException!");
	  }

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

                    السطر الأول
	  السطر الثاني
	

الكلاس FileInputStream في جافا

يستخدم هذا الكلاس لقراءة البيانات من الملفات. و هو يحتوي على أكثر من كونستركتور.


الكونستركتور التالي نمرر له إسم الملف كـ String لإنشاء كائن الـ InputStream و الذي من خلاله يمكن قراءة الملف. مثال:

                  InputStream is = new FileInputStream("C://MyFiles//test.txt")
  

الكونستركتور التالي نمرر له كائن نوعه File لإنشاء كائن الـ InputStream و الذي من خلاله يمكن قراءة الملف. يجب إنشاء كائن الـ File قبله. مثال:

                  File f = new File("C://MyFiles//test.txt")
	InputStream is = new FileInputStream(f);
  


بعد أن يصبح كائن الـ InputStream جاهزاً, يمكنك إستخدام الكثير من الدوال الجاهزة لقراءة الملف أو لفعل أي شيء آخر.

الدالة مع تعريفها
public void close() throws IOException تغلق الـ InputStream و تقطع الإتصال بين الـ Stream و أي مصدر كان متصلاً فيه.
public int read() throws IOException في كل مرة تقرأ byte جديدة من بيانات الـ InputStream و ترجعها كقيمة نوعها int بين 255-0.
ترجع 1- إذا وصلت لنهاية الملف.
public int read(byte[] b) throws IOException تقرأ مجموعة جديدة من الـ bytes من بيانات الـ InputStream في كل مرة تستدعى فيها و تخزنهم في المصفوفة b و ترجعها كـ int.
ترجع 1- إذا وصلت لنهاية الملف.
public int available() throws IOException ترجع عدد الـ bytes الذي يمكن قراءتهم من الـ InputStream و ترجع 0 عند الوصول لنهاية الملف.


مثال

في هذا المثال سنقوم بإنشاء ملف جديد و كتابة بعض البيانات فيه, ثم سنقوم بقراءة هذه البيانات من الملف.

Main.java
                    import java.io.InputStream;
	  import java.io.OutputStream;
	  import java.io.FileInputStream;
	  import java.io.FileOutputStream;
	  import java.io.IOException;

	  public class Main {

	  public static void main(String[] args) {

	  try {
	  // لخلق ملف جديد و الذي سنكتب قيم المصفوفة فيه OutputStream هنا قمنا بإنشاء مصفوفة, و قمنا بإنشاء كائن نوعه
	  byte[] bytes = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
	  OutputStream os = new FileOutputStream("test.txt");

	  // هنا قمنا بكتابة قيم المصفوفة في الملف
	  for (int i=0; i<bytes.length; i++) {
	  os.write( bytes[i] );
	  }
	  os.close();

	  // و الذي سنقرأ بواسطته محتوى الملف InputStream هنا قمنا بإنشاء كائن نوعه
	  InputStream is = new FileInputStream("test.txt");

	  // size الموجودين في الملف في المتغير bytes هنا قمنا بتخزين عدد الـ
	  int size = is.available();

	  // موجودة في الملف byte هنا قمنا بقراءة و عرض كل
	  for (int i=0; i<size; i++) {
	  System.out.print( is.read() + " " );
	  }
	  is.close();
	  }
	  catch(IOException e) {
	  System.out.println("There is IOException!");
	  }

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

                    1 2 3 4 5 6 7 8 9 10
	

الكلاس ByteArrayInputStream في جافا

الكلاس ByteArrayInputStream يسمح باستخدام الـ buffer في الذاكرة كـ InputStream. و هو يقرأ البيانات من المصدر كمصفوفة نوعها byte.


الكلاس ByteArrayInputStream يحتوي على الـ constructors المذكورين في الجدول التالي.

الكونستركتور مع تعريفه
public ByteArrayInputStream(byte[] buf) يقبل مصفوفة نوعها byte كـ argument.
المصفوفة buf هي التي ستوضع كما هي في الـ buffer.
public ByteArrayInputStream(byte[] buf, int off, int len) يأخذ مصفوفة من الـ bytes, و متغيرين آخرين نوعهما int.
المتغير off يقصد به من أي عنصر في المصفوفة buf سيكتب في الـ buffer.
المتغير len يقصد به كم عنصر من عناصر المصفوفة buf سيكتب في الـ buffer.


بعد أن يصبح كائن الـ ByteArrayInputStream جاهزاً, يمكنك إستخدام الكثير من الدوال الجاهزة لقراءة الملف أو لفعل أي شيء آخر.

الدالة مع تعريفها
public int read() في كل مرة تستدعى فيها تقرأ byte جديدة من بيانات الـ InputStream و ترجعها كقيمة نوعها int بين 255-0.
و ترجع 1- إذا وصلت لنهاية الملف.
public int read(byte[] b, int off, int len) في كل مرة تستدعى فيها تقرأ مجموعة bytes جديدة من بيانات الـ InputStream و تخزنهم في المصفوفة b.
المتغير off يقصد به من أي عنصر في المصفوفة b سيكتب في الـ InputStream.
المتغير len يقصد به كم عنصر من عناصر المصفوفة b سيكتب في الـ InputStream.
public int available() ترجع عدد الـ bytes الذي يمكن قراءتهم من الـ InputStream و ترجع 0 عند الوصول لنهاية الملف.

الكلاس DataInputStream في جافا

الكلاس DataInputStream يستخدم لقراءة البيانات البدائية primitive data types من ملف معين.


الكونستركتور التالي ينشئ كائن DataInputStream و الذي من خلاله يمكن قراءة الملف. مثال:

                  InputStream in = new DataInputStream(InputStream in)
  

بعد أن يصبح كائن الـ InputStream جاهزاً, يمكنك إستخدام الكثير من الدوال الجاهزة لقراءة الملف أو لفعل أي شيء آخر.

الدالة مع تعريفها
public final int read() throws IOException في كل مرة تستدعى فيها تقرأ بعض الـ bytes من بيانات الـ InputStream و تخزنهم في المصفوفة b ثم ترجع عدد البيانات الذي قرأته.
ترجع 1- إذا وصلت لنهاية الملف.
public final int read(byte[] b, int off, int len) throws IOException في كل مرة تستدعى فيها تقرأ مجموعة bytes جديدة من بيانات الـ InputStream و تخزنهم في المصفوفة b.
المتغير off يقصد به من أي عنصر في المصفوفة b سيكتب في الـ InputStream.
المتغير len يقصد به كم عنصر من عناصر المصفوفة b سيكتب في الـ InputStream.
public String readLine() throws IOException في كل مرة تستدعى فيها تقرأ بيانات سطر جديد من الـ InputStream. تقرأ الـ bytes بالترتيب الموجودين فيه مع تحويل كل byte بشكل منفصل إلى حرف. في الأخير ترجع الأحرف التي قرأتها كـ String.
public final boolean readBoolean() throws IOException في كل مرة تستدعى فيها تقرأ 1 byte من الـ InputStream. و ترجعها كـ boolean.
public final byte readByte() throws IOException في كل مرة تستدعى فيها تقرأ 1 byte من الـ InputStream. و ترجعها كـ byte.
public final char readChar() throws IOException في كل مرة تستدعى فيها تقرأ 2 bytes من الـ InputStream. و ترجعهم كـ short.
public final int readInt() throws IOException في كل مرة تستدعى فيها تقرأ 4 bytes من الـ InputStream. و ترجعهم كـ int.


مثال

في هذا المثال سنقوم بإنشاء ملف جديد و كتابة نص صغير فيه, ثم سنقوم بقراءة النص من الملف.

Main.java
                    import java.io.DataInputStream;
	  import java.io.DataOutputStream;
	  import java.io.FileInputStream;
	  import java.io.FileOutputStream;
	  import java.io.IOException;

	  public class Main {

	  public static void main(String[] args) throws IOException {

	  // UTF-8 ملاحظة هنا يعتمد الترميز .fis من خلال الكائن DataOutputStream هنا قمنا بإنشاء كائن نوعه
	  DataOutputStream dos = new DataOutputStream(new FileOutputStream("C:\\myFiles\\example.txt"));

	  // هنا قمنا بكتابة نص في الملف
	  dos.writeUTF("harmash.com" + "\n" + "أفضل موقع عربي لتعلم البرمجة");

	  // UTF-8 ملاحظة هنا يعتمد الترميز .dos من خلال الكائن DataInputStream هنا قمنا بإنشاء كائن نوعه
	  DataInputStream dis = new DataInputStream(new FileInputStream("C:\\myFiles\\example.txt"));

	  // هنا قمنا بقراءة محتوى الملف ثم عرضه
	  while (dis.available()>0) {
	  String k = dis.readUTF();
	  System.out.print(k);
	  }

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

                    harmash.com
	  أفضل موقع عربي لتعلم البرمجة 
	

الكلاس FileOutputStream في جافا

يستخدم هذا الكلاس لإنشاء ملف جديد و كتابة البيانات فيه.
في حال وجود ملف يحمل نفس الإسم و النوع في نفس المسار الموضوع للـ OutputStream, سيتم تبديل الملف القديم بملف الـ OutputStreamالجديد.


يحتوي هذا الكلاس على أكثر من كونستركتور.

الكونستركتور التالي نمرر له إسم الملف كـ String لإنشاء كائن الـ OutputStream و الذي من خلاله يمكن قراءة الملف. مثال:

                  OutputStream is = new FileOutputStream("C://MyFiles//test.txt")
  

الكونستركتور التالي نمرر له كائن نوعه File لإنشاء كائن الـ OutputStream و الذي من خلاله يمكن قراءة الملف. يجب إنشاء كائن الـ File قبله. مثال:

                  File f = new File("C://MyFiles//test.txt")
	OutputStream is = new FileOutputStream(f); 
  

بعد أن يصبح كائن الـ OutputStream جاهزاً, يمكنك إستخدام الكثير من الدوال الجاهزة لقراءة الملف أو لفعل أي شيء آخر.

الدالة مع تعريفها
public void close() throws IOException تغلق الـ OutputStream و تقطع الإتصال بين الـ Stream و أي مصدر كان متصلاً فيه.
public abstract write(int b) throws IOException تكتب الـ byte التي تمرر لها كـ argumentفي الـ OutputStream.
public int write(byte[] b) throws IOException تكتب مجموعة الـ bytes الموجودين في المصفوفة b في الـ OutputStream.
public int wirte(byte[] b, int off, int len) throws IOException تكتب مجموعة من الـ bytes الموجودين في المصفوفة b في الـ OutputStream.
المتغير off يقصد به من أي عنصر في المصفوفة b سيكتب في الـ OutputStream.
المتغير len يقصد به كم عنصر من عناصر المصفوفة b سيكتب في الـ OutputStream.


مثال

في هذا المثال سنقوم بإنشاء ملف جديد و كتابة بعض البيانات فيه, ثم سنقوم بقراءة هذه البيانات من الملف.

Main.java
                    import java.io.InputStream;
	  import java.io.OutputStream;
	  import java.io.FileInputStream;
	  import java.io.FileOutputStream;
	  import java.io.IOException;

	  public class Main {

	  public static void main(String[] args) {

	  try {
	  // لخلق ملف جديد و الذي سنكتب قيم المصفوفة فيه OutputStream هنا قمنا بإنشاء مصفوفة, و قمنا بإنشاء كائن نوعه
	  byte[] bytes = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
	  OutputStream os = new FileOutputStream("test.txt");

	  // هنا قمنا بكتابة قيم المصفوفة في الملف
	  for (int i=0; i<bytes.length; i++) {
	  os.write( bytes[i] );
	  }
	  os.close();

	  // و الذي سنقرأ بواسطته محتوى الملف InputStream هنا قمنا بإنشاء كائن نوعه
	  InputStream is = new FileInputStream("test.txt");

	  // size الموجودين في الملف في المتغير bytes هنا قمنا بتخزين عدد الـ
	  int size = is.available();

	  // موجودة في الملف byte هنا قمنا بقراءة و عرض كل
	  for (int i=0; i<size; i++) {
	  System.out.print( is.read() + " " );
	  }
	  is.close();
	  }
	  catch(IOException e) {
	  System.out.println("There is IOException!");
	  }

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

                    1 2 3 4 5 6 7 8 9 10
	

الكلاس ByteArrayOutputStream في جافا

الكلاس ByteArrayOutputStream ينشئ buffer في الذاكرة لتخزين بيانات الـ Stream فيها قبل إرسالها للـ OutputStream.


الكلاس ByteArrayOutputStream يحتوي على الـ constructors المذكورين في الجدول التالي.

الكونستركتور مع تعريفه
public ByteArrayOutputStream() ينشئ كائن ByteArrayOutputStream يملك buffer تتألف من 32 bytes.
public ByteArrayOutputStream(int bufSize) ينشئ كائن ByteArrayOutputStream يملك buffer تتألف من الحجم الذي تدخله له.


بعد أن يصبح كائن الـ ByteArrayOutputStream جاهزاً, يمكنك إستخدام الكثير من الدوال الجاهزة لقراءة الملف أو لفعل أي شيء آخر.

الدالة مع تعريفها
public int reset() تستخدم لتصفير الـ buffer ( أي لمسح جميع البيانات الموجودة فيها ), أي سيتم مسح جميع البيانات الموجودة في كائن ByteArrayOutputStream.
public byte toByteArray() تنشئ مصفوفة جديدة نوعها byte, حجمها يساوي حجم الـ ByteArrayOutputStream و المحتوى الموجود في الـ Buffer يتم نسخه فيها.
ترجع محتوى الـ ByteArrayOutputStream كمصفوفة نوعها byte.
public String toString() تحول محتوى الـ buffer لقيمة String. يتم تحويل القيمة هنا حسب الترميز المستخدم.
public void write(int b) تكتب الـ byte التي تعطى لها كـ argument في الـ ByteArrayOutputStream.
public void write(byte[] b, int off, int len) في كل مرة تستدعى فيها تكتب مجموعة bytes من المصفوفة b في الـ OutputStream.
المتغير off يقصد به من أي عنصر في المصفوفة b سيكتب في الـ OutputStream.
المتغير len يقصد به كم عنصر من عناصر المصفوفة b سيكتب في الـ OutputStream.
public void write(OutputStream out) throws IOException تكتب محتوى كائن الـ OutputStream الذي قام باستدعائها في كائن الـ OutputStream الذي يعطى لها كـ argument.

الكلاس DataOutputStream في جافا

الكلاس DataOutputStream يستخدم لكتابة البيانات البدائية primitive data types في ملف معين.


الكونستركتور التالي ينشئ كائن DataOutputStream و الذي من خلاله يمكن قراءة الملف. مثال:

                  OutputStream in = new DataOutputStream(OutputStream ou)
  

بعد أن يصبح كائن الـ OutputStream جاهزاً, يمكنك إستخدام الكثير من الدوال الجاهزة لقراءة الملف أو لفعل أي شيء آخر.

الدالة مع تعريفها
public final int write(int b) تكتب الـ byte التي تعطى لها كـ argument في كائن الـ OutputStream.
ترجع عدد الـ bytes الذي تم كتابته في الـ buffer.
public final void write(byte[] b, int off, int len) في كل مرة تستدعى فيها تكتب مجموعة bytes من المصفوفة b في كائن الـ OutputStream.
المتغير off يقصد به من أي عنصر في المصفوفة b سيكتب في كائن الـ OutputStream.
المتغير len يقصد به كم عنصر من عناصر المصفوفة b سيكتب في كائن الـ OutputStream.
public final void writeBoolean() throws IOException في كل مرة تستدعى فيها تكتب قيمة boolean تتألف من 1 byte في كائن الـ OutputStream.
public final void writeByte() throws IOException في كل مرة تستدعى فيها تكتب قيمة byte تتألف من 1 byte في كائن الـ OutputStream.
public final void writeChar() throws IOException في كل مرة تستدعى فيها تكتب قيمة char تتألف من 2 bytes في كائن الـ OutputStream.
public final void writeInt() throws IOException في كل مرة تستدعى فيها تكتب قيمة int يتم كتابتها كـ 4 bytes في كائن الـ OutputStream.
public void flush() throws IOException تضمن كتابة جميع البيانات الموجودة في الـ buffer في كائن الـ OutputStream ثم تقوم بمسح جميع البيانات من الـ buffer.


مثال

في هذا المثال سنقوم بإنشاء ملف جديد و كتابة نص صغير فيه, ثم سنقوم بقراءة النص من الملف.

Main.java
                    import java.io.DataInputStream;
	  import java.io.DataOutputStream;
	  import java.io.FileInputStream;
	  import java.io.FileOutputStream;
	  import java.io.IOException;

	  public class Main {

	  public static void main(String[] args) throws IOException {

	  // UTF-8 ملاحظة هنا يعتمد الترميز .fis من خلال الكائن DataOutputStream هنا قمنا بإنشاء كائن نوعه
	  DataOutputStream dos = new DataOutputStream(new FileOutputStream("C:\\myFiles\\example.txt"));

	  // هنا قمنا بكتابة نص في الملف
	  dos.writeUTF("harmash.com" + "\n" + "أفضل موقع عربي لتعلم البرمجة");

	  // UTF-8 ملاحظة هنا يعتمد الترميز .dos من خلال الكائن DataInputStream هنا قمنا بإنشاء كائن نوعه
	  DataInputStream dis = new DataInputStream(new FileInputStream("C:\\myFiles\\example.txt"));

	  // هنا قمنا بقراءة محتوى الملف ثم عرضه
	  while (dis.available()>0) {
	  String k = dis.readUTF();
	  System.out.print(k);
	  }

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

                    harmash.com
	  أفضل موقع عربي لتعلم البرمجة 
	

الكلاس File في جافا

الكلاس File يمثل جميع أنواع الملفات و المجلدات و المسارات.
يستخدم هذا الكلاس لفحص الملفات, المجلدات, البحث عن ملفات, مسح ملفات إلخ..

كائن الـ File الذي تقوم بإنشاءه, يمثل ملف أو مجلد معين موجود في الجهاز.


الكلاس File يحتوي على الـ constructors المذكورين في الجدول التالي.

الكونستركتور مع تعريفه
public File(File parent, String child) ينشئ كائن جديد من الـ File الموجود في المسار parent, و الذي إسمه child.
public File(String pathname) ينشئ كائن جديد من الـ File الذي يشير إليه الـ pathname.
public File(String parent, String child) ينشئ كائن جديد من الـ File الموجود في المسار parent, و الذي إسمه child.
public File(URI uri) ينشئ كائن جديد من الـ File الذي يشير إليه الـ uri.


بعد أن يصبح كائن الـ File جاهزاً, يمكنك إستخدام الكثير من الدوال الجاهزة لقراءة الملف أو لفعل أي شيء آخر.

الدالة مع تعريفها
public String getName() ترجع إسم الملف أو المجلد الذي يشير إليه مسار كائن الـ File الذي قام باستدعائها.
public String getParent() ترجع المسار الأب للملف أو المجلد الذي يشير إليه كائن الـ File الذي قام باستدعائها كـ String.
أو ترجع null إذا كان المسار الموضوع غير موجود.
public File getParent() ترجع المسار الأب للملف أو المجلد الذي يشير إليه كائن الـ File الذي قام باستدعائها كـ File.
أو ترجع null إذا كان المسار الموضوع غير موجود.
public String getPath() تحول المسار الذي يشير إليه كائن الـ File الذي قام باستدعائها إلى String.
public boolean isAbsolute() تختبر المسار الذي يشير إليه كائن الـ File الذي قام باستدعائها لمعرفة إذا كان absolute أم لا.
ترجع true إذا كان absolute و ترجع false إذا لم يكن كذلك.
public String getAbsolutePath() ترجع المسار الـ absolute للمسار الذي يشير إليه كائن الـ File الذي قام باستدعائها.
public boolean canRead() تختبر إذا كان البرنامج يقدر أن يقرأ من الملف الذي يشير إليه كائن الـ File الذي قام باستدعائها.
ترجع true إذا كان الملف موجود و يمكن قراءته. غير ذلك ترجع false.
public boolean canWrite() تختبر إذا كان البرنامج يقدر أن يكتب في الملف الذي يشير إليه كائن الـ File الذي قام باستدعائها.
ترجع true إذا كان الملف موجود و يمكن الكتابة فيه. غير ذلك ترجع false.
public boolean exist() تختبر إذا كان الملف أو المجلد الذي يشير إليه كائن الـ File الذي قام باستدعائها موجوداً أم لا.
ترجع true إذا كان الملف موجود. غير ذلك ترجع false.
public boolean isFile() تختبر إذا كان الملف الذي يشير إليه كائن الـ File الذي قام باستدعائها هو ملف عادي (normal file) أم لا.
ملف عادي تعني ليس مجلد, أي ليس directory. أي ملف عادي تم إنشائه من خارج تطبيقات جافا يعتبر مباشرةً ملف عادي.
ترجع true إذا كان الملف موجود و إذا لم يكن directory. غير ذلك ترجع false.
public boolean isDirectory() تختبر إذا كان الملف الذي يشير إليه كائن الـ File الذي قام باستدعائها هو مجلد (directory) أم لا.
ترجع true إذا كان الملف موجود و إذا كان directory. غير ذلك ترجع false.
public long lastModified() ترجع وقت آخر مرة تم فيها تعديل الملف الذي يشير إليه كائن الـ File الذي قام باستدعائها. الوقت الذي ترجعه هو وقت بالـ milliseconds منذ ( 1/1/1970 00:00:00 GMT ), أو ترجع 0L إذا كان الملف غير موجود أو في حال حدوث أي خطأ.
public long length() ترجع طول الملف الذي يشير إليه مسار كائن الـ File الذي قام باستدعائها بالـ bytes. و ترجع 0L إذا لم يكن الملف موجود أو إذا كان المسار يشير إلى مجلد.
public boolean createNewFile() throws IOException تنشئ ملف جديد فارغ في المسار الذي يشير إليه كائن الـ File في حال كان لا يشير إلى ملف موجود أصلاً.
ترجع true إذا كان الملف غير موجود و إذا تم إنشاءه بنجاح. غير ذلك ترجع false.
public boolean delete() تمسح الملف أو المجلد الذي يشير إليه كائن الـ File الذي قام باستدعائها. إذا كان المجلد فارغاً يجب أن يكون فارغاً حتى يتم مسحه.
ترجع true إذا تم مسح الملف أو المجلد. غير ذلك ترجع false.
public void deleteOnExit() ترسل طلب إلى الـ JVM يقضي بمسح الملف أو المجلد الذي يشير إليه كائن الـ File الذي قام باستدعائها عند الإنتهاء من تنفيذ أوامر البرنامج.
public String[] list() ترجع مصفوفة نوعها String تحتوي على أسماء الملفات و المجلدات الموجودة في المسار الذي يشير إليه كائن الـ File الذي قام باستدعائها.
public File[] listFiles() ترجع مصفوفة نوعها File تحتوي على مسارات جميع الملفات و المجلدات الموجودة في المسار الذي يشير إليه المجلد الذي يشير إليه كائن الـ File الذي قام باستدعائها.
public boolean mkdir() تنشئ مجلد في المسار الذي يشير إليه كائن الـ File.
ترجع true إذا تم إنشاء الملف. غير ذلك ترجع false.
public boolean mkdirs() تنشئ مجلد في المسار الذي يشير إليه كائن الـ File الذي قام باستدعائها.
هنا في حال كان المسار الموضوع غير موجود ستقوم هي بإنشاءه. أي ستنشئ جميع المجلدات الموضوعة في المسار.
ترجع true إذا تم إنشاء الملف. غير ذلك ترجع false.
public boolean renameTo(File dest) تستخدم لإعطاء إسم جديد للملف الذي يشير إليه كائن الـ File الذي قام باستدعائها. الإسم الذي يعطى للكائن dest هو الإسم الجديد الذي سيعطى للملف.
ترجع true إذا تمت العملية بنجاح. غير ذلك ترجع false.
public boolean setLastModified(long time) تستخدم لتغيير آخر وقت تم فيه تعديل الملف يشير إليه كائن الـ File الذي قام باستدعائها.
ترجع true إذا تمت العملية بنجاح. غير ذلك ترجع false.
public boolean setReadOnly(long time) تستخدم لجعل الملف الذي يشير إليه كائن الـ File الذي قام باستدعائها يملك صلاحية الـ read only. هذه الصلاحية تمنع أي عملية تعديل أو كتابة في الملف و تسمح فقط بقراءة محتواه.
ترجع true إذا تمت العملية بنجاح. غير ذلك ترجع false.
public static File createTempFile(String prefix, String suffix, File directory) throws IOException تستخدم لإنشاء ملف مؤقت, أي ملف يتم مسحه تلقائياً عند إنتهاء الـ JVM من تنفيذ أوامر البرنامج.
prefix هو إسم الملف الذي سيتم إنشاءه, suffix هو نوع الملف الذي سيتم إنشاءه. directory هو الذي سيتم إنشاء الملف فيه.
ترجع مسار الملف الذي تم إنشاءه.
public static File createTempFile(String prefix, String suffix) throws IOException تستخدم لإنشاء ملف مؤقت, أي ملف يتم مسحه تلقائياً عند إنتهاء الـ JVM من تنفيذ أوامر البرنامج.
الملف هنا يتم إنشاءه في المكان الذي تحفظ فيه الملفات الإفتراضية على الجهاذ.
prefix هو إسم الملف الذي سيتم إنشاءه, suffix هو نوع الملف الذي سيتم إنشاءه.
ترجع مسار الملف الذي تم إنشاءه.
public int compareTo(File pathname) تقارن أحرف مسارين مع بعض. أي مسار الكائن الذي قام باستدعاءها مع مسار الكائن pathname.
ترجع 0 إذا كان مسار الكائن الذي قام باستدعاءها يساوي مسار الكائن pathname.
ترجع عدد أصغر من 0 إذا كان مسار الكائن الذي قام باستدعاءها أكبر من مسار الكائن pathname.
ترجع عدد أكبر من 0 إذا كان مسار الكائن الذي قام باستدعاءها أصغر من مسار الكائن pathname.
public int compareTo(Object obj) تقارن أحرف مسارين مع بعض. أي مسار الكائن الذي قام باستدعاءها مع مسار أي كائن نضعه كـ argument.
ترجع 0 إذا كان مسار الكائن الذي قام باستدعاءها يساوي مسار الكائن obj.
ترجع عدد أصغر من 0 إذا كان مسار الكائن الذي قام باستدعاءها أكبر من مسار الكائن obj.
ترجع عدد أكبر من 0 إذا كان مسار الكائن الذي قام باستدعاءها أصغر من مسار الكائن obj.
public boolean equals(Object obj) تختبر الكائن الذي قام باستدعاءها مع أي كائن نضعه كـ argument.
ترجع true إذا كانت قيمة الكائنين لا تساوي null و إذا كان الكائنين عندهم نفس المسار سواء كان يشير إلى ملف أو إلى مجلد. غير ذلك ترجع false.
public String toString() ترجع إسم الملف أو المجلد الذي يشير إليه مسار كائن الـ File الذي قام باستدعائها كـ String.
و هي مثل الدالة getPath().


مثال

في هذا المثال سنقوم بإنشاء كائن نوعه File يشير إلى ملف معين, ثم سنعرض فقط بعض خصائص هذا الملف.

Main.java
                    import java.io.File;

	  public class Main {

	  public static void main(String[] args) {

	  // File هنا قمنا بإنشاء كائن نوعه
	  File f = null;

	  try {

	  // f هنا قمنا بتحديد الملف الذي يشير إليه الكائن
	  f = new File("C:\\MyFiles\\input.txt");

	  // يشير إلى ملف أو مجلد موجود سيتم عرض جميع خصائصه f هنا قلنا إذا كان الكائن
	  if(f.exists()) {
	  System.out.println("File name:              " +f.getName());
	  System.out.println("File length:            " +f.length());
	  System.out.println("File parent path:       " +f.getParent());
	  System.out.println("File absolute path:     " +f.getAbsolutePath());
	  System.out.println("File read permission:   " +f.canRead());
	  System.out.println("File write permission:  " +f.canWrite());

	  // يشير إلى مجلد, سيتم عرض جميع الأشياء الموجودة بداخله f هنا قلنا إذا كان الكائن
	  if (f.isDirectory()) {
	  System.out.println("\n" +f.getName()+ " contains:");
	  File files[] = f.listFiles();
	  for(int i=0; i<files.length; i++) {
	  System.out.println((i+1)+") "+files[i].getName());
	  }
	  }
	  }
	  // لا يشير لأي ملف أو مجلد موجود سيعرض أن الملف غير موجود f هنا قلنا إذا كان الكائن
	  else {
	  System.out.println("File not exists!");
	  }

	  }
	  catch(Exception e) {
	  System.out.println("There is Exception!");
	  }

	  }

	  }
	

سنحصل على نتيجة تشبه النتيجة التالية عند التشغيل.

                    File name:              input.txt
	  File length:            70
	  File parent path:       C:\MyFiles
	  File absolute path:     C:\MyFiles\input.txt
	  File read permission:   true
	  File write permission:  true 
	

في حال قمنا بتغيير مسار الكائن f لجعله يشير إلى المجلد MyFiles, سنحصل على النتيجة التالية عند التشغيل.

                    File name:              MyFiles
	  File length:            4096
	  File parent path:       C:\
	  File absolute path:     C:\MyFiles
	  File read permission:   true
	  File write permission:  true

	  MyFiles contains:
	  1) input.txt
	  2) intro.MP4
	  3) hacker song.MP3
	  4) output.txt
	  5) folder 1
	  6) folder 2