क्या मुझे FileReader और BufferedReader दोनों को बंद करने की आवश्यकता है?


188

मैं एक स्थानीय फ़ाइल का उपयोग कर एक बफ़र-राइडर का उपयोग कर रहा हूँ जो एक 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();

इस विधि को सर्वलेट से कहा जाता है, और मैं यह सुनिश्चित करना चाहता हूं कि मैं किसी भी हैंडल को खुला न छोड़ूं।


4
Y'know, आप सिर्फ इस तरह से जानकारी के लिए स्रोत पढ़ सकते हैं। यह सब वहाँ है JDK स्थापना निर्देशिका में src.zip में, या आप इसे ऑनलाइन पढ़ सकते हैं उदाहरण के लिए docjar.com/html/api/java/io/BufferedReader.java.html
gustafc

50
स्रोत को पढ़ने के लिए किसी को बताना "RTFM!" कहने से भी बदतर है। और अगर स्रोत में बग है तो क्या होगा; संक्षेप में हम जानना चाहते हैं कि सही व्यवहार क्या है?
राएडवल्ड

1
ठीक है ... इस दृष्टिकोण से: एपीआई स्पेक्स की ओर इशारा करना तब कोई बेहतर नहीं है। यदि स्रोत बग का कारण नहीं है, तो यह व्यवहार नहीं करता है कि यह डॉक्स में निर्दिष्ट है, तो आप डॉक्स पर भरोसा नहीं कर सकते। इसलिए इस तरह के सवाल का जवाब देने का कोई अच्छा तरीका नहीं है।
Atmocreations

@Atmocreations अगली रखरखाव रिलीज़ किसी बग को ठीक से ठीक कर सकती है जिस पर आप भरोसा करते हैं यदि आप स्रोत को देखते हैं। आपको वास्तव में यह जानने की जरूरत है कि दस्तावेज व्यवहार क्या है। स्रोत को देखने में कुछ भी गलत नहीं है, लेकिन आप यह नहीं मान सकते कि स्रोत नहीं बदलेगा। दस्तावेज़ व्यवहार को बदलना आमतौर पर बग को ठीक करने की तुलना में बहुत बड़ा सौदा है।
जेम्स मूर

जवाबों:


202

नहीं।

BufferedReader.close()

BufferedReader और InputStreamReader के लिए javadoc के अनुसार स्ट्रीम बंद करता है

साथ ही साथ

FileReader.close()

कर देता है।


12
जब तक कि कंस्ट्रक्टर BufferedReaderअपवाद न फेंके। यह केवल अंतर्निहित धारा को बंद करने के लिए क्लीनर है, हालांकि आपको अन्य संसाधनों और बफरिंग के साथ सज्जाकारों के लिए बाहर देखने की आवश्यकता है।
टॉम हॉल्टिन -

9
Javadoc यह नहीं कहता कि BufferedReader.close()अंतर्निहित पाठक को बंद करता है या नहीं । इसका वर्णन बस से कॉपी किया गया है Reader.close()। यह व्यवहार में वास्तविक व्यवहार हो सकता है, लेकिन यह प्रलेखित नहीं है।
जॉन कुगेलमैन

3
यदि वास्तविक व्यवहार अलग था, तो इसे इस तरह से प्रलेखित किया जाना चाहिए था। अन्यथा प्रलेखन बेकार है। प्रोग्रामर प्रलेखन को पूर्ण और विशिष्ट मानने में सक्षम होना चाहिए।
Atmocreations

6
इससे कोई फर्क नहीं पड़ता कि वास्तविक दस्तावेज को बदलना चाहिए था या नहीं बदलना चाहिए था, Reader#close()जेवाडॉक का कहना नहीं है कि यह बंद हो गया है या नहीं यह लिपटे रीडर है या नहीं। यह सब उससे संबंधित है Closes the stream and releases any system resources associated with it.जो यह कहने के लिए पर्याप्त नहीं है कि यह संसाधन बंद करता है या नहीं करता है। 'संसाधन जारी करें' हो सकता है कि बफ़रडेयर में संसाधन के किसी भी संदर्भ को हटा दिया जाए ... जिसका अर्थ है कि संसाधन बंद नहीं है।
searchengine27

99

जैसा कि दूसरों ने बताया है, आपको केवल बाहरी आवरण को बंद करने की आवश्यकता है।

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

एक बहुत ही पतला मौका है कि यह एक फ़ाइल हैंडल को लीक कर सकता है अगर BufferedReaderनिर्माणकर्ता ने एक अपवाद (जैसे OutOfMemoryError) फेंक दिया । यदि आपका ऐप इस स्थिति में है, तो आपके क्लीन अप को कितने सावधान रहने की आवश्यकता है, यह इस बात पर निर्भर हो सकता है कि यह कितना महत्वपूर्ण है कि आप ओएस को संसाधनों से वंचित न करें, जो अन्य कार्यक्रमों के लिए आवंटित करना चाहते हैं।

Closeable अगर एक आवरण निर्माता जावा 5 या 6 में असफल हो जाने की संभावना है इंटरफेस का इस्तेमाल किया जा सकता है:

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

जावा 7 कोड को संसाधनों के साथ प्रयोग करने की कोशिश करनी चाहिए :

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

1
"जावा 7 कोड को कोशिश-के-संसाधनों के पैटर्न का उपयोग करना चाहिए"। धन्यवाद, ठीक यही मैं देख रहा था। यह समाधान '09 में लिखा गया था, इसलिए संसाधनों के साथ-साथ प्रतिमान शायद नई सिफारिश होनी चाहिए। Furthemore, यह स्वीकृत और उच्च मतदान वाले उत्तर पर OP को बेहतर उत्तर देता है।
tresf

5

बफ़रडाइडर स्रोत के अनुसार, इस मामले में bReader.close कॉल fReader.close इसलिए तकनीकी रूप से आपको बाद वाले को कॉल करने की आवश्यकता नहीं है।


यह देखते हुए कि दस्तावेज का उपयोग यह बताते हुए किया जाता है कि इसका उपयोग कैसे किया जाना चाहिए, आपको पहले दस्तावेज को देखना चाहिए - कोड में कोई भी विचलन बग है।
हमीज़ेल विलाप से इस्तीफा दे देती है

5

BufferedReader के लिए स्रोत कोड दिखाता है कि जब आप BufferedReader को बंद करते हैं तो अंतर्निहित बंद हो जाता है।


1
मैं वास्तव में इसे कुछ ठोस से जोड़ने के लिए एक अंगूठे को देना चाहता हूं, लेकिन यह केवल OpenJDK कार्यान्वयन को संदर्भित करता है, और चूंकि JavaDocs के लिए अस्पष्ट हैं Reader#close(), इसलिए यह ठोस सबूत प्रदान नहीं करता है कि उदाहरण के लिए, Oracle JDK एक में लागू किया गया है इसी तरह का फ़ैशन।
searchengine27

4

स्रोत कोड की जाँच करने के बाद, मैंने पाया कि उदाहरण के लिए:

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

बफ़रड्रेडर ऑब्जेक्ट पर क्लोज़ () विधि रीडर क्लास का एब्स्ट्रैक्ट क्लोज़ () तरीका कहेगी जो अंततः इनपुटस्ट्रीमरेडर क्लास में कार्यान्वित विधि को कॉल करेगा , जो तब इनपुटस्ट्रीम ऑब्जेक्ट को बंद कर देता है ।

तो, केवल bReader.close () पर्याप्त है।


4
स्रोत कोड क्या दिखाता है एक संदर्भ के रूप में उपयुक्त नहीं है। यह वही है जो विनिर्देश कहता है, इस मामले में जावदोक, जिस पर भरोसा किया जा सकता है।
लोरेन का मार्कीस

1

Java 7 से शुरू होकर आप try-with-Resources कथन का उपयोग कर सकते हैं

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

क्योंकि BufferedReaderकोशिश-के-संसाधन विवरण में उदाहरण घोषित किया गया है, चाहे वह सामान्य रूप से या अचानक पूरा हो गया हो या नहीं, यह बंद हो जाएगा। इसलिए आपको finallyबयान में इसे स्वयं बंद करने की आवश्यकता नहीं है । (यह नेस्टेड रिसोर्स स्टेटमेंट के मामले में भी है)

संसाधनों के साथ काम करने का यह तरीका है, अधिक विस्तृत जानकारी के लिए दस्तावेज़ीकरण देखें


यह 2009 से @ mcdowell के उत्तर के लगभग समान है, जिसमें कुछ किनारे-मामले भी शामिल हो सकते हैं जो हो सकते हैं।
tresf

0

आपको केवल बफ़र करने की आवश्यकता है ब्रेडर को बंद कर दें अर्थात रीडर। क्लोज़ () और यह ठीक काम करेगा।


0

मुझे देर हो गई है, लेकिन:

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;
        }
    }
}

Eeeeh कि उसके सवाल का जवाब नहीं है? वह / वह पूछता है कि क्या FileReader और BufferedReader को बंद करना आवश्यक है, उदाहरण कोड नहीं।
टोरनेक्सो

@ TornaxO7 नहीं, यह एक उदाहरण कोड नहीं है। मैंने सिर्फ जावा सोर्स कोड का हिस्सा लिखा है। इसलिए, यदि आप ctrl / cmd कुंजी (IDE पर निर्भर करता है) के साथ कुछ बफ़ररेडर के फंक्शन पर क्लिक करते हैं, तो आप बफ़रड्रेडर के सोर्स कोड देख सकते हैं, और आप कोड के उस टुकड़े को पा सकते हैं। तो, जैसा कि आप BufferedReader बस पास FileReader से ही देख सकते हैं ( 'में' इस मामले में FileReader है, इसलिए, जब आप bufferReader.close () फोन यह in.close () के अंदर कहता है, वास्तव में bufferReader.close विधि में)
दिमित्री गशको

0

आपको लिपटे पाठक / लेखक को बंद करने की आवश्यकता नहीं है।

आप डॉक्स पर एक नज़र ली हैं ( Reader.close(), Writer.close()), आप देखेंगे कि में Reader.close()यह कहते हैं:

धारा को बंद कर देता है और इससे जुड़े किसी भी सिस्टम संसाधन को जारी करता है।

जो सिर्फ यह कहता है कि यह "इससे जुड़े किसी भी सिस्टम संसाधन को जारी करता है"। हालांकि यह पुष्टि नहीं करता है .. यह आपको गहराई से देखना शुरू करने के लिए एक कुहनी से हलका धक्का देता है। और यदि आप इसके पास जाते हैं Writer.close()तो केवल यह बताता है कि यह अपने आप बंद हो जाता है।

ऐसे मामलों में, हम स्रोत कोड पर एक नज़र लेने के लिए OpenJDK का उल्लेख करते हैं ।

BufferedWriter लाइन 265 पर आप देखेंगे out.close()। तो यह खुद को बंद नहीं कर रहा है .. यह कुछ और है। आप "की आवृत्तियां के लिए वर्ग खोज करते हैं out" आप कम से निर्माता में पता चलेगा कि लाइन 87 कि outवर्ग wraps जहां यह एक और निर्माता कहता है और उसके बाद है लेखक बताए outअपने आप को पैरामीटर outचर ..

तो .. दूसरों के बारे में क्या? आप इसी तरह के कोड को बफ़रड्रेडर लाइन 514 , बफ़रडइनप्यूटस्ट्रीम लाइन 468 और इनपुटस्ट्रीमरेज़ लाइन 199 पर देख सकते हैं । दूसरों को मैं नहीं जानता, लेकिन यह मानने के लिए पर्याप्त होना चाहिए कि वे क्या करते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.