आप बाहरी सबसे स्ट्रीम को बंद कर सकते हैं, वास्तव में आपको लिपटे सभी धाराओं को बनाए रखने की आवश्यकता नहीं है और आप जावा 7 ट्राइ-विथ-रिसोर्स का उपयोग कर सकते हैं।
try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
new GZIPOutputStream(new FileOutputStream(createdFile)))) {
// write to the buffered writer
}
यदि आप YAGNI की सदस्यता लेते हैं, या आप-नहीं-आने-जरूरत-यह करते हैं, तो आपको केवल उसी कोड को जोड़ना चाहिए जो आपको वास्तव में चाहिए। आपको वह कोड नहीं जोड़ना चाहिए जिसकी आप कल्पना करते हैं कि आपको आवश्यकता हो सकती है लेकिन वास्तव में कुछ भी उपयोगी नहीं है।
इस उदाहरण को लें और कल्पना करें कि क्या गलत हो सकता है अगर आपने ऐसा नहीं किया और इसका क्या प्रभाव होगा?
try (
OutputStream outputStream = new FileOutputStream(createdFile);
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream);
OutputStreamWriter osw = new OutputStreamWriter(gzipOutputStream);
BufferedWriter bw = new BufferedWriter(osw)
) {
// ...
}
चलिए FileOutputStream से शुरू करते हैं जो open
सभी वास्तविक कार्य करने के लिए कहता है।
/**
* Opens a file, with the specified name, for overwriting or appending.
* @param name name of file to be opened
* @param append whether the file is to be opened in append mode
*/
private native void open(String name, boolean append)
throws FileNotFoundException;
यदि फ़ाइल नहीं मिली है, तो बंद करने के लिए कोई अंतर्निहित संसाधन नहीं है, इसलिए इसे बंद करने से कोई फर्क नहीं पड़ेगा। यदि फ़ाइल मौजूद है, तो उसे FileNotFoundException को फेंकना चाहिए। इसलिए इस लाइन से संसाधन को बंद करने की कोशिश करने से कुछ हासिल नहीं होगा।
फ़ाइल को सफलतापूर्वक खोलने के लिए आपको फ़ाइल बंद करने का कारण है, लेकिन बाद में आपको एक त्रुटि मिलती है।
अगली धारा को देखते हैं GZIPOutputStream
कोड है जो एक अपवाद फेंक सकता है
private void writeHeader() throws IOException {
out.write(new byte[] {
(byte) GZIP_MAGIC, // Magic number (short)
(byte)(GZIP_MAGIC >> 8), // Magic number (short)
Deflater.DEFLATED, // Compression method (CM)
0, // Flags (FLG)
0, // Modification time MTIME (int)
0, // Modification time MTIME (int)
0, // Modification time MTIME (int)
0, // Modification time MTIME (int)
0, // Extra flags (XFLG)
0 // Operating system (OS)
});
}
यह फाइल का हैडर लिखता है। अब आपके लिए यह बहुत ही असामान्य हो जाएगा कि आप लिखने के लिए एक फ़ाइल खोलने में सक्षम हों, लेकिन इसके लिए 8 बाइट्स भी नहीं लिख पाएंगे, लेकिन यह कल्पना कर सकते हैं कि ऐसा हो सकता है और हम बाद में फ़ाइल को बंद नहीं करते हैं। यदि यह बंद न हो तो किसी फाइल का क्या होगा?
आपको कोई भी अप्रकाशित लिख नहीं मिलता है, उन्हें छोड़ दिया जाता है और इस मामले में, धारा में सफलतापूर्वक कोई बाइट्स नहीं लिखा जाता है जो इस बिंदु पर किसी भी तरह से बफर नहीं होता है। लेकिन एक फाइल जो बंद नहीं है वह हमेशा के लिए नहीं रहती है, इसके बजाय FileOutputStream के पास है
protected void finalize() throws IOException {
if (fd != null) {
if (fd == FileDescriptor.out || fd == FileDescriptor.err) {
flush();
} else {
/* if fd is shared, the references in FileDescriptor
* will ensure that finalizer is only called when
* safe to do so. All references using the fd have
* become unreachable. We can call close()
*/
close();
}
}
}
यदि आप किसी फ़ाइल को बिल्कुल भी बंद नहीं करते हैं, तो यह वैसे भी बंद हो जाती है, बस तुरंत नहीं (और जैसा मैंने कहा, डेटा जो एक बफर में छोड़ दिया गया है वह इस तरह से खो जाएगा, लेकिन इस बिंदु पर कोई भी नहीं है)
फ़ाइल को तुरंत बंद न करने का परिणाम क्या है? सामान्य परिस्थितियों में, आप संभावित रूप से कुछ डेटा खो देते हैं, और आप संभावित रूप से फ़ाइल डिस्क्रिप्टर से बाहर निकल जाते हैं। लेकिन अगर आपके पास एक ऐसी प्रणाली है जहाँ आप फाइलें बना सकते हैं, लेकिन आप उन्हें कुछ नहीं लिख सकते हैं, तो आपको बड़ी समस्या है। यानी यह कल्पना करना कठिन है कि आप बार-बार इस फाइल को बनाने की कोशिश कर रहे हैं कि आप असफल क्यों हो रहे हैं।
दोनों OutputStreamWriter और BufferedWriter अपने कंस्ट्रक्टर्स में IOException नहीं फेंकते हैं, इसलिए यह स्पष्ट नहीं है कि वे किस समस्या का कारण बनेंगे। बफ़र किए गए वैटर के मामले में, आपको एक आउटऑफ़मैरीऑरर मिल सकता है। इस मामले में यह तुरंत एक जीसी को ट्रिगर करेगा, जैसा कि हमने देखा है कि वैसे भी फाइल बंद हो जाएगी।