سؤال

أنا أقرأ ملفًا محليًا باستخدام قائد Bufferredreader ملفوف حول قائد FileReader:

BufferedReader reader = new BufferedReader(new FileReader(fileName));
// read the file
// (error handling snipped)
reader.close();

هل أنا بحاجة ل close() ال FileReader كذلك ، أم أن الغلاف يتعامل مع ذلك؟ لقد رأيت رمزًا حيث يفعل الناس شيئًا كهذا:

FileReader fReader = new FileReader(fileName);
BufferedReader bReader = new BufferedReader(fReader);
// read the file
// (error handling snipped)
bReader.close();
fReader.close();

هذه الطريقة تسمى من servlet ، وأود أن أتأكد من أنني لا أترك أي مقابض مفتوحة.

هل كانت مفيدة؟

المحلول

لا.

BufferedReader.close()

يغلق الدفق حسب جافادوك ل BufferedReader و InputStreamReader

إلى جانب

FileReader.close()

يفعل.

نصائح أخرى

كما أشار الآخرون ، تحتاج فقط إلى إغلاق الغلاف الخارجي.

BufferedReader reader = new BufferedReader(new FileReader(fileName));

هناك فرصة ضئيلة للغاية لأن هذا يمكن أن يتسرب مقبض ملف إذا كان BufferedReader ألقى مُنشئ استثناء (على سبيل المثال OutOfMemoryError). إذا كان التطبيق الخاص بك في هذه الحالة ، فإن مدى حذر التنظيف الخاص بك قد يعتمد على مدى أهمية أنك لا تحرم نظام التشغيل من الموارد التي قد ترغب في تخصيصها للبرامج الأخرى.

ال قابلة للإغلاق يمكن استخدام الواجهة إذا كان من المحتمل أن يفشل مُنشئ الغلاف في Java 5 أو 6:

Reader reader = new FileReader(fileName);
Closeable resource = reader;
try {
  BufferedReader buffered = new BufferedReader(reader);
  resource = buffered;
  // TODO: input
} finally {
  resource.close();
}

يجب استخدام رمز Java 7 تجرب مع الموارد نمط:

try (Reader reader = new FileReader(fileName);
    BufferedReader buffered = new BufferedReader(reader)) {
  // TODO: input
}

وفقًا لمصدر BufferredReader ، في هذه الحالة ، Quarer.Close Call Freader.Close حتى من الناحية الفنية لا تضطر إلى الاتصال بالأخير.

رمز المصدر ل BufferedReader يوضح أن الأساس يتم إغلاقه عند إغلاق قائد Bufferreader.

بعد التحقق من رمز المصدر ، وجدت ذلك على سبيل المثال:

FileReader fReader = new FileReader(fileName);
BufferedReader bReader = new BufferedReader(fReader);

طريقة الإغلاق () BufferedReader سيقوم الكائن بتسمية طريقة الإغلاق التجريدي () قارئ الفئة التي من شأنها أن تسمي في النهاية الطريقة التي تم تنفيذها في InputStreamReader الطبقة التي تغلق ثم تيار الإدخال هدف.

لذلك ، فقط Quarer.Close () يكفي.

بدءًا من Java 7 يمكنك استخدامه بيان المحاولة مع الموارد

try (BufferedReader br = new BufferedReader(new FileReader(path))) {
    return br.readLine();
}

بسبب ال BufferedReader يتم الإعلان عن مثيل في بيان المحاولة مع الموارد ، سيتم إغلاقه بغض النظر عما إذا كان بيان المحاولة يكمل بشكل طبيعي أو مفاجئ. لذلك لا تحتاج إلى إغلاقه بنفسك في finally بيان. (هذا هو الحال أيضًا مع بيانات الموارد المتداخلة)

هذه هي الطريقة التي تم إعادة تشغيلها للعمل مع الموارد ، راجع توثيق لمزيد من المعلومات التفصيلية

تحتاج فقط إلى إغلاق قارئ IE BufferreadReader.close () وسيعمل بشكل جيد.

لقد تأخرت ، لكن:

bufferreader.java:

public BufferedReader(Reader in) {
  this(in, defaultCharBufferSize);
}

(...)

public void close() throws IOException {
    synchronized (lock) {
        if (in == null)
            return;
        try {
            in.close();
        } finally {
            in = null;
            cb = null;
        }
    }
}

أنت لا تحتاج إلى إغلاق القارئ/الكاتب ملفوف.

إذا كنت قد ألقيت نظرة على المستندات (Reader.close(),Writer.close()) ، سترى ذلك في Reader.close() انها تقول:

يغلق الدفق ويطلق أي موارد النظام المرتبطة به.

الذي يقول فقط أنه "يطلق أي موارد النظام مرتبطة مع ذلك ". Writer.close() ينص فقط على أنه يغلق نفسه.

في مثل هذه الحالات ، نشير إلى OpenJdk لإلقاء نظرة على رمز المصدر.

في المخزن المؤقت الخط 265 سوف ترى out.close(). لذلك لا يغلق نفسه .. إنه شيء آخر. إذا بحثت في الفصل عن حدث ""out"ستلاحظ ذلك في المُنشئ في الخط 87 الذي - التي out هل الكاتب يلف الفصل حيث يدعو مُنشئًا آخر ثم تعيينه out المعلمة الخاصة بها out عامل..

لذا .. ماذا عن الآخرين؟ يمكنك رؤية رمز مماثل في BufferedReader Line 514, BufferedInputStream Line 468 و InputStreamReader Line 199. آخرون لا أعرفهم ولكن هذا يجب أن يكون كافياً لافتراض أنهم يفعلون ذلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top