إغلاق التدفقات بأمان
استخدم try-with-resources
إغلاق التدفقات بأمان درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.
لماذا نغلق التدفقات
تحتفظ التدفقات مثل BufferedReader بـموارد النظام، مثل مقابض الملفات ومخازن الذاكرة المؤقتة والاتصالات. إذا لم تغلقها مطلقًا، فقد تتسرّب هذه الموارد.
يحرّر إغلاق التدفق الموارد التي يحتفظ بها، ويدفع أي بيانات معلّقة إلى وجهتها. يوضّح هذا الدرس كيفية القيام بذلك بأمان.
الدالة close
يحتوي كل قارئ على الدالة close(). ويؤدي استدعاؤها إلى تحرير المورد.
عند تغليف System.in باستخدام BufferedReader، يؤدي الإغلاق أيضًا إلى إغلاق التدفقات الأساسية التي يغلفها.
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
// ... use br ...
br.close();الطريقة القديمة المحفوفة بالمخاطر
يمكنك استدعاء close() يدويًا، ولكن إذا حدث خطأ قبل تنفيذ ذلك السطر، فسيتم تجاوز close() ويتسرّب المورد.
يساعد وضع close() في كتلة finally، لكنه مطوّل ومن السهل تنفيذه بطريقة خاطئة.
BufferedReader br = null;
try {
br = new BufferedReader(
new InputStreamReader(System.in));
// ... use br ...
} finally {
if (br != null) br.close();
}try-with-resources
توفّر Java حلًا أنظف يُسمّى try-with-resources. تعلن عن التدفق داخل الأقواس بعد try، وتغلقه Java تلقائيًا عند انتهاء الكتلة، حتى إذا حدث خطأ.
لا تحتاج إلى finally ولا إلى استدعاء close() يدويًا. هذه هي أفضل ممارسة حديثة.
try (BufferedReader br =
new BufferedReader(new InputStreamReader(System.in))) {
String line = br.readLine();
System.out.println(line);
}كيف تعمل
يجب أن يطبّق أي مورد يتم التصريح عنه داخل أقواس try (...) الواجهة AutoCloseable. ويطبّقها BufferedReader، لذلك تستدعي Java الدالة close() نيابةً عنك.
يحدث الإغلاق بعد انتهاء الكتلة، سواء انتهت بشكل طبيعي أو بسبب استثناء.
مثال كامل
إليك برنامجًا كاملًا يستخدم try-with-resources لقراءة سطر واحد. يُغلق القارئ تلقائيًا عند نهاية الكتلة.
يقرأ البرنامج من System.in، لذلك ينتظر الإدخال ولا يمكن تشغيله تلقائيًا هنا.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
try (BufferedReader br = new BufferedReader(
new InputStreamReader(System.in))) {
String name = br.readLine();
System.out.println("Hi " + name);
}
}
}قابل للتشغيل باستخدام StringReader
لإثبات أن try-with-resources يعمل دون إدخال من لوحة المفاتيح، يقرأ هذا المثال من StringReader. ويمكن تشغيله بالكامل.
بعد انتهاء الكتلة، يُغلق القارئ تلقائيًا، ولا تكتب أي استدعاء للدالة close().
import java.io.BufferedReader;
import java.io.StringReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
try (BufferedReader br =
new BufferedReader(new StringReader("done"))) {
System.out.println(br.readLine());
}
}
}موارد متعددة
يمكنك التصريح عن عدة موارد في جملة try واحدة، مع الفصل بينها بفواصل منقوطة. وتغلقها Java جميعًا بترتيب عكسي لترتيب التصريح عنها.
يكون ذلك مفيدًا عند تغليف عدة تدفقات معًا.
try (InputStreamReader isr =
new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr)) {
System.out.println(br.readLine());
}التعامل مع IOException
قد تؤدي القراءة إلى طرح IOException. يمكنك إضافة catch إلى كتلة try-with-resources للتعامل معه بدلًا من التصريح عن throws.
يُغلق المورد تلقائيًا قبل تنفيذ catch مع ذلك.
try (BufferedReader br = new BufferedReader(
new InputStreamReader(System.in))) {
System.out.println(br.readLine());
} catch (IOException e) {
System.out.println("Read failed");
}هل ينبغي إغلاق System.in؟
هناك تنبيه مهم: يؤدي إغلاق قارئ على System.in أيضًا إلى إغلاق System.in نفسه، ولا يمكنك إعادة فتحه.
لا توجد مشكلة في ذلك بالنسبة إلى البرامج القصيرة. ولكن إذا كنت لا تزال تحتاج إلى إدخال من وحدة التحكم لاحقًا، فلا تغلق ذلك القارئ تحديدًا. احرص على معرفة ما الذي يغلفه تدفقك.
أفضل الممارسات
للتعامل مع التدفقات بأمان:
- فضّل try-with-resources على استدعاء
close()يدويًا. - يُغلق التدفق تلقائيًا حتى عند حدوث الأخطاء.
- تذكّر أن إغلاق قارئ
System.inيؤدي إلى إغلاق الإدخال القياسي.
تمنع إدارة الموارد بطريقة سليمة حدوث التسريبات والأخطاء.
تحقّق سريع
فكّر في الفائدة الأساسية من try-with-resources.
مراجعة
تعلّمت سبب ضرورة إغلاق التدفقات، ومخاطر النهج اليدوي باستخدام finally، ونمط try-with-resources النظيف الذي يغلق موارد AutoCloseable تلقائيًا.
يمكنك الآن قراءة الإدخال باستخدام BufferedReader بأمان من البداية إلى النهاية.
الأسئلة الشائعة
هل درس «إغلاق التدفقات بأمان» مجاني؟
نعم — نص درس «إغلاق التدفقات بأمان» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.
ماذا ستتعلم في «إغلاق التدفقات بأمان»؟
استخدم try-with-resources تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟
لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «إغلاق التدفقات بأمان»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟
نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- لماذا نستخدم BufferedReader
- قراءة الأسطر
- تحليل الأرقام من الإدخال
- إغلاق التدفقات بأمان