केवल एक संसाधन का उपयोग करते समय जावा 7 ट्राइ -रिसोर्स रिसोर्स सिंटैक्स (जिसे ARM ब्लॉक ( ऑटोमैटिक रिसोर्स मैनेजमेंट ) भी कहा जाता है ) अच्छा, छोटा और सीधा है AutoCloseable
। हालांकि, मुझे यकीन नहीं है कि सही मुहावरा क्या है जब मुझे कई संसाधनों की घोषणा करने की आवश्यकता होती है जो एक दूसरे पर निर्भर होते हैं, उदाहरण के लिए एक FileWriter
और एक BufferedWriter
इसे लपेटता है। बेशक, यह सवाल किसी भी मामले में चिंता करता है जब कुछ AutoCloseable
संसाधनों को लपेटा जाता है, न केवल इन दो विशिष्ट वर्गों को।
मैं निम्नलिखित तीन विकल्पों के साथ आया:
1)
भोली मुहावरे मैंने देखा है कि एआरएम-प्रबंधित चर में केवल शीर्ष-स्तरीय आवरण घोषित करना है:
static void printToFile1(String text, File file) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
bw.write(text);
} catch (IOException ex) {
// handle ex
}
}
यह अच्छा और छोटा है, लेकिन यह टूट गया है। क्योंकि अंतर्निहित FileWriter
को एक चर में घोषित नहीं किया गया है, यह सीधे उत्पन्न finally
ब्लॉक में बंद नहीं होगा । यह केवल close
लपेटने की विधि के माध्यम से बंद हो जाएगा BufferedWriter
। समस्या यह है, कि यदि एक अपवाद को bw
कंस्ट्रक्टर से फेंका जाता है, तो close
उसे कॉल नहीं किया जाएगा और इसलिए अंतर्निहित FileWriter
को बंद नहीं किया जाएगा ।
2)
static void printToFile2(String text, File file) {
try (FileWriter fw = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(fw)) {
bw.write(text);
} catch (IOException ex) {
// handle ex
}
}
यहां, एआरएम-प्रबंधित चर में अंतर्निहित और रैपिंग संसाधन दोनों घोषित किए जाते हैं, इसलिए दोनों को निश्चित रूप से बंद कर दिया जाएगा, लेकिन अंतर्निहित fw.close()
को केवल दो बार बुलाया जाएगा : न केवल सीधे, बल्कि रैपिंग के माध्यम से भी bw.close()
।
यह इन दो विशिष्ट वर्गों के लिए एक समस्या नहीं होनी चाहिए जो दोनों लागू करते हैं Closeable
(जो कि इसका एक उपप्रकार है AutoCloseable
), जिसका अनुबंध बताता है कि close
अनुमति के लिए कई कॉल हैं:
इस स्ट्रीम को बंद कर देता है और इससे जुड़े किसी भी सिस्टम रिसोर्सेस को रिलीज़ करता है। यदि धारा पहले से ही बंद है तो इस विधि को लागू करने से कोई प्रभाव नहीं पड़ता है।
हालांकि, एक सामान्य मामले में, मेरे पास ऐसे संसाधन हो सकते हैं जो केवल AutoCloseable
(और नहीं Closeable
) को लागू करते हैं , जो इसकी गारंटी नहीं देता हैclose
कई बार कहा जा सकता है:
ध्यान दें कि java.io.Closeable की करीबी विधि के विपरीत, इस नज़दीकी विधि को बेवकूफ़ बनाने की आवश्यकता नहीं है। दूसरे शब्दों में, क्लोज़ेबिल के विपरीत इस क्लोज विधि को एक से अधिक बार करने से कुछ दृश्य दुष्प्रभाव हो सकते हैं, जिन्हें एक से अधिक बार कॉल करने पर कोई प्रभाव नहीं पड़ता है। हालांकि, इस इंटरफ़ेस के कार्यान्वयनकर्ताओं को अपने करीबी तरीकों को उदासीन बनाने के लिए दृढ़ता से प्रोत्साहित किया जाता है।
3)
static void printToFile3(String text, File file) {
try (FileWriter fw = new FileWriter(file)) {
BufferedWriter bw = new BufferedWriter(fw);
bw.write(text);
} catch (IOException ex) {
// handle ex
}
}
यह संस्करण सैद्धांतिक रूप से सही होना चाहिए, क्योंकि केवल fw
एक वास्तविक संसाधन का प्रतिनिधित्व करता है जिसे साफ करने की आवश्यकता होती है। bw
खुद किसी भी संसाधन नहीं रखता है, यह केवल करने के लिए प्रतिनिधियोंfw
, तो यह केवल पास अंतर्निहित लिए पर्याप्त होना चाहिए fw
।
दूसरी ओर, सिंटैक्स थोड़ा अनियमित है और इसके अलावा, ग्रहण एक चेतावनी जारी करता है, जो मुझे लगता है कि एक गलत अलार्म है, लेकिन यह अभी भी एक चेतावनी है कि किसी को भी इससे निपटना है:
संसाधन रिसाव: 'bw' कभी बंद नहीं होता है
तो, किस दृष्टिकोण के लिए जाना है? या मैंने कुछ अन्य मुहावरे याद किए हैं जो सही हैं ?
public BufferedWriter(Writer out, int sz)
एक फेंक सकते हैं IllegalArgumentException
। इसके अलावा, मैं एक वर्ग के साथ बफ़रड्राइवर का विस्तार कर सकता हूं जो इसके निर्माता से कुछ फेंक देगा या मुझे जो भी आवश्यक होगा, वह कस्टम आवरण बना देगा।
BufferedWriter
निर्माता आसानी से एक अपवाद फेंक कर सकते हैं। OutOfMemoryError
संभवतः यह सबसे आम है क्योंकि यह बफर के लिए मेमोरी का एक अच्छा हिस्सा आवंटित करता है (हालांकि यह इंगित कर सकता है कि आप पूरी प्रक्रिया को फिर से शुरू करना चाहते हैं)। / आप की जरूरत है flush
अपने BufferedWriter
यदि आप बंद नहीं करते हैं और सामग्री (आम तौर पर रखना चाहते हैं केवल गैर अपवाद मामला)। FileWriter
"डिफ़ॉल्ट" फ़ाइल एन्कोडिंग होने के लिए जो कुछ भी होता है उसे उठाता है - यह स्पष्ट होना बेहतर है।