प्रयास-साथ-संसाधन ब्लॉक में कई जंजीर संसाधनों के प्रबंधन के लिए सही मुहावरा?


168

केवल एक संसाधन का उपयोग करते समय जावा 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' कभी बंद नहीं होता है


तो, किस दृष्टिकोण के लिए जाना है? या मैंने कुछ अन्य मुहावरे याद किए हैं जो सही हैं ?


4
बेशक, यदि अंतर्निहित FileWriter का कंस्ट्रक्टर एक अपवाद फेंकता है, तो यह खुलता भी नहीं है और सब कुछ ठीक है। 1 उदाहरण के बारे में क्या है, अगर FileWriter निर्मित हो जाता है, तो क्या होता है, लेकिन BufferedWriter का निर्माता इसके अपवाद को फेंकता है।
नैटिक्स

6
यह ध्यान देने योग्य है कि बफ़रड्राइवर एक अपवाद नहीं फेंकेंगे। क्या कोई उदाहरण है जहां आप सोच सकते हैं कि यह प्रश्न शुद्ध शैक्षणिक नहीं है।
पीटर लॉरी

10
@PeterLawrey हां, आप सही हैं कि इस परिदृश्य में बफ़रड्राइवर के निर्माता सबसे अधिक अपवाद नहीं फेंकेंगे, लेकिन जैसा कि मैंने बताया है, यह सवाल किसी भी सज्जाकार-शैली के संसाधनों की चिंता करता है। लेकिन उदाहरण के लिए public BufferedWriter(Writer out, int sz)एक फेंक सकते हैं IllegalArgumentException। इसके अलावा, मैं एक वर्ग के साथ बफ़रड्राइवर का विस्तार कर सकता हूं जो इसके निर्माता से कुछ फेंक देगा या मुझे जो भी आवश्यक होगा, वह कस्टम आवरण बना देगा।
Natix

5
BufferedWriterनिर्माता आसानी से एक अपवाद फेंक कर सकते हैं। OutOfMemoryErrorसंभवतः यह सबसे आम है क्योंकि यह बफर के लिए मेमोरी का एक अच्छा हिस्सा आवंटित करता है (हालांकि यह इंगित कर सकता है कि आप पूरी प्रक्रिया को फिर से शुरू करना चाहते हैं)। / आप की जरूरत है flushअपने BufferedWriterयदि आप बंद नहीं करते हैं और सामग्री (आम तौर पर रखना चाहते हैं केवल गैर अपवाद मामला)। FileWriter"डिफ़ॉल्ट" फ़ाइल एन्कोडिंग होने के लिए जो कुछ भी होता है उसे उठाता है - यह स्पष्ट होना बेहतर है।
टॉम हॉन्टिन -

10
@ नैटिक्स मैं चाहता हूं कि एसओ में सभी प्रश्न उतना ही शोधपूर्ण और स्पष्ट हो जितना कि यह है। मेरी इच्छा है कि मैं इस 100 बार मतदान कर सकूं।
गीक

जवाबों:


75

यहाँ मेरा विकल्प पर ले लो:

1)

try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
    bw.write(text);
}

मेरे लिए, 15 साल पहले पारंपरिक सी ++ से जावा में सबसे अच्छी बात यह थी कि आप अपने कार्यक्रम पर भरोसा कर सकते थे। यहां तक ​​कि अगर चीजें गड़बड़ में हैं और गलत हो रही हैं, जो वे अक्सर करते हैं, तो मैं चाहता हूं कि बाकी कोड सर्वश्रेष्ठ व्यवहार और गुलाब की महक पर हों। वास्तव में, BufferedWriterएक अपवाद यहाँ फेंक सकता है। उदाहरण के लिए, स्मृति से बाहर चलना असामान्य नहीं होगा। अन्य सज्जाकारों के लिए, क्या आप जानते हैं कि कौन से java.ioरैपर वर्ग अपने कंस्ट्रक्टरों से चेक किए गए अपवाद को फेंक देते हैं? मैं नही। यदि आप उस तरह के अस्पष्ट ज्ञान पर भरोसा करते हैं तो कोड समझने की क्षमता को बहुत अच्छा नहीं करता है।

इसके अलावा "विनाश" है। यदि कोई त्रुटि स्थिति है, तो आप संभवतः उस फ़ाइल को रगड़ना नहीं चाहते हैं जिसे हटाने की आवश्यकता है (कोड जो नहीं दिखाया गया है)। हालाँकि, ज़ाहिर है, फ़ाइल को डिलीट करना भी एरर हैंडलिंग के रूप में करने के लिए एक और दिलचस्प ऑपरेशन है।

आम तौर पर आप चाहते हैं कि finallyब्लॉक यथासंभव कम और विश्वसनीय हों। फ्लश जोड़ने से इस लक्ष्य में मदद नहीं मिलती है। कई रिलीज के लिए JDK में कुछ बफ़रिंग वर्गों में एक बग था जहां सजाए गए ऑब्जेक्ट पर कारण के flushभीतर से एक अपवाद को नहीं बुलाया जाएगा। जब तक कि कुछ समय के लिए तय किया गया है, अन्य कार्यान्वयन से इसकी अपेक्षा करें।closeclose

2)

try (
    FileWriter fw = new FileWriter(file);
    BufferedWriter bw = new BufferedWriter(fw)
) {
    bw.write(text);
}

हम अभी भी अंतर्निहित अंततः ब्लॉक में फ्लश कर रहे हैं (अब दोहराया के साथ close- यह बदतर हो जाता है क्योंकि आप अधिक सज्जाकार जोड़ते हैं), लेकिन निर्माण सुरक्षित है और हमें अंत में ब्लॉक करना होगा ताकि एक असफल भी flushसंसाधन जारी न होने पाए ।

3)

try (FileWriter fw = new FileWriter(file)) {
    BufferedWriter bw = new BufferedWriter(fw);
    bw.write(text);
}

यहाँ एक बग है। होना चाहिए:

try (FileWriter fw = new FileWriter(file)) {
    BufferedWriter bw = new BufferedWriter(fw);
    bw.write(text);
    bw.flush();
}

कुछ खराब लागू सज्जाकार वास्तव में संसाधन हैं और उन्हें मज़बूती से बंद करने की आवश्यकता होगी। इसके अलावा कुछ धाराओं को एक विशेष तरीके से बंद करने की आवश्यकता हो सकती है (शायद वे संपीड़न कर रहे हैं और समाप्त करने के लिए बिट्स लिखने की जरूरत है, और बस सब कुछ फ्लश नहीं कर सकते।

निर्णय

हालांकि 3 एक तकनीकी रूप से बेहतर समाधान है, सॉफ्टवेयर विकास के कारण 2 बेहतर विकल्प बनाते हैं। हालाँकि, प्रयास-के साथ-संसाधन अभी भी एक अपर्याप्त सुधार है और आपको एक्ज़्यूट अराउंड मुहावरे के साथ रहना चाहिए , जिसमें जावा एसई 8 में क्लोजर के साथ एक स्पष्ट वाक्यविन्यास होना चाहिए।


4
संस्करण 3 में, आप कैसे जानते हैं कि बीडब्ल्यू को अपने करीबी को बुलाया जाने की आवश्यकता नहीं है? और यहां तक ​​कि अगर आप सुनिश्चित हो सकते हैं यदि यह है, तो क्या यह भी "अस्पष्ट ज्ञान" नहीं है जैसा कि आपने संस्करण 1 के लिए उल्लेख किया है?
तैमुक

3
" सॉफ्टवेयर विकास के कारण 2 बेहतर विकल्प बनाते हैं " क्या आप इस विवरण को अधिक विस्तार से बता सकते हैं?
डंकन जोन्स

8
क्या आप "बंद होने के साथ मुहावरे के आसार" का उदाहरण दे सकते हैं
मार्कस

2
क्या आप समझा सकते हैं "जावा एसई 8 में क्लोजर के साथ स्पष्ट सिंटैक्स" क्या है?
पेट्टार्क

1
"मुहावरे के आस
चर्चा

20

पहली शैली ओरेकल द्वारा सुझाई गई हैBufferedWriterजाँच किए गए अपवादों को नहीं फेंकता है, इसलिए यदि कोई अपवाद फेंका जाता है, तो प्रोग्राम को इससे उबरने की उम्मीद नहीं होती है, जिससे संसाधन ज्यादातर लूट की स्थिति में आ जाते हैं।

ज्यादातर इसलिए कि यह एक थ्रेड में हो सकता है, थ्रेड मरने के साथ लेकिन कार्यक्रम अभी भी जारी है - कहते हैं, एक अस्थायी मेमोरी आउटेज था जो बाकी प्रोग्राम को गंभीरता से बिगाड़ने के लिए पर्याप्त नहीं था। हालाँकि, यह एक कोने का मामला है, हालाँकि, और अगर ऐसा होता है कि संसाधन रिसाव को समस्या बनाने के लिए अक्सर पर्याप्त होता है, तो कोशिश के साथ-संसाधन आपकी समस्याओं में से कम से कम है।


2
यह प्रभावी जावा के तीसरे संस्करण में अनुशंसित दृष्टिकोण भी है।
shmosel

5

विकल्प 4

यदि आप कर सकते हैं, तो अपने संसाधनों को क्लोजेबल होने के लिए बदलें, न कि ऑटोक्लोबल। तथ्य यह है कि निर्माणकर्ताओं का जिक्र किया जा सकता है इसका मतलब यह है कि संसाधन को दो बार बंद करना अनसुना नहीं है। (यह एआरएम से पहले भी सच था।) नीचे इस पर और अधिक।

विकल्प 5

एआरएम का उपयोग न करें और कोड को सुनिश्चित करने के लिए बहुत सावधानी से () दो बार नहीं बुलाया जाता है!

विकल्प 6

एआरएम का उपयोग न करें और एक कोशिश / पकड़ में खुद को अंततः बंद () कॉल करें।

मुझे नहीं लगता कि यह समस्या एआरएम के लिए अद्वितीय है

इन सभी उदाहरणों में, अंत में बंद () कॉल एक कैच ब्लॉक में होनी चाहिए। पठनीयता के लिए छोड़ दिया।

कोई भी अच्छा नहीं क्योंकि fw को दो बार बंद किया जा सकता है। (जो FileWriter के लिए ठीक है लेकिन आपके काल्पनिक उदाहरण में नहीं है):

FileWriter fw = null;
BufferedWriter bw = null;
try {
  fw = new FileWriter(file);
  bw = new BufferedWriter(fw);
  bw.write(text);
} finally {
  if ( fw != null ) fw.close();
  if ( bw != null ) bw.close();
}

कोई अच्छा नहीं है क्योंकि fw बंद नहीं है अगर एक बफ़रड्राइवर के निर्माण पर अपवाद है। (फिर से, नहीं हो सकता, लेकिन आपके काल्पनिक उदाहरण में):

FileWriter fw = null;
BufferedWriter bw = null;
try {
  fw = new FileWriter(file);
  bw = new BufferedWriter(fw);
  bw.write(text);
} finally {
  if ( bw != null ) bw.close();
}

3

मैं सिर्फ एआरएम का उपयोग नहीं करने के जीन के बॉयार्स्की के सुझाव पर निर्माण करना चाहता था, लेकिन यह सुनिश्चित करना कि फाइलवर्टर हमेशा एक बार बिल्कुल बंद हो जाता है। लगता है कि यहाँ कोई समस्या नहीं है ...

FileWriter fw = null;
BufferedWriter bw = null;
try {
    fw = new FileWriter(file);
    bw = new BufferedWriter(fw);
    bw.write(text);
} finally {
    if (bw != null) bw.close();
    else if (fw != null) fw.close();
}

मुझे लगता है कि चूंकि एआरएम सिर्फ सिंथेटिक चीनी है, हम हमेशा इसे अंततः ब्लॉकों को बदलने के लिए उपयोग नहीं कर सकते हैं। जैसे हम हमेशा कुछ करने के लिए फॉर-लूप का उपयोग नहीं कर सकते हैं जो पुनरावृत्तियों के साथ संभव है।


5
यदि आपके tryऔर finallyब्लॉक दोनों अपवाद छोड़ देते हैं, तो यह निर्माण पहले (और संभवतः अधिक उपयोगी) एक को खो देगा।
आरएक्सजी

3

पहले की टिप्पणियों से सहमत होने के लिए: संसाधनों का उपयोग करने के लिए सबसे सरल (2) है Closeableऔर कोशिश-के साथ संसाधनों के खंड में उन्हें घोषित करना है। यदि आपके पास केवल है AutoCloseable, तो आप उन्हें दूसरे (नेस्टेड) ​​वर्ग में लपेट सकते हैं जो कि बस जाँच करता हैclose केवल एक बार (मुखौटा पैटर्न), उदाहरण के लिए private bool isClosed;। व्यवहार में भी ओरेकल सिर्फ (1) निर्माणकर्ताओं को जंजीर देता है और श्रृंखला के माध्यम से अपवादों को सही ढंग से संभाल नहीं पाता है।

वैकल्पिक रूप से, आप स्थैतिक कारखाने विधि का उपयोग करके मैन्युअल रूप से एक जंजीर संसाधन बना सकते हैं; यह चेन को इनकैप्सुलेट करता है, और अगर वह पार्ट-वे फेल होता है तो क्लीनअप को हैंडल करता है:

static BufferedWriter createBufferedWriterFromFile(File file)
  throws IOException {
  // If constructor throws an exception, no resource acquired, so no release required.
  FileWriter fileWriter = new FileWriter(file);
  try {
    return new BufferedWriter(fileWriter);  
  } catch (IOException newBufferedWriterException) {
    try {
      fileWriter.close();
    } catch (IOException closeException) {
      // Exceptions in cleanup code are secondary to exceptions in primary code (body of try),
      // as in try-with-resources.
      newBufferedWriterException.addSuppressed(closeException);
    }
    throw newBufferedWriterException;
  }
}

इसके बाद आप संसाधनों के साथ-साथ क्लॉज में एकल संसाधन के रूप में इसका उपयोग कर सकते हैं:

try (BufferedWriter writer = createBufferedWriterFromFile(file)) {
  // Work with writer.
}

जटिलता कई अपवादों को संभालने से आती है; अन्यथा यह सिर्फ "करीबी संसाधन हैं जो आपने अब तक हासिल किए हैं"। ऐसा लगता है कि एक सामान्य अभ्यास पहले उस चर को शुरू करता है जो उस संसाधन को रखता है जो संसाधन रखता हैnull (यहां fileWriter) , और फिर सफाई में एक शून्य जांच शामिल है, लेकिन यह अनावश्यक लगता है: यदि निर्माण विफल रहता है, तो सफाई करने के लिए कुछ भी नहीं है, इसलिए हम केवल उस अपवाद को प्रचारित कर सकते हैं, जो कोड को थोड़ा सरल करता है।

आप शायद ऐसा उदारतापूर्वक कर सकते हैं:

static <T extends AutoCloseable, U extends AutoCloseable, V>
    T createChainedResource(V v) throws Exception {
  // If constructor throws an exception, no resource acquired, so no release required.
  U u = new U(v);
  try {
    return new T(u);  
  } catch (Exception newTException) {
    try {
      u.close();
    } catch (Exception closeException) {
      // Exceptions in cleanup code are secondary to exceptions in primary code (body of try),
      // as in try-with-resources.
      newTException.addSuppressed(closeException);
    }
    throw newTException;
  }
}

इसी तरह, आप तीन संसाधनों की श्रृंखला कर सकते हैं, आदि।

एक तरफ एक गणितीय के रूप में, आप एक समय में दो संसाधनों का पीछा करते हुए भी तीन बार चेन कर सकते हैं, और यह साहचर्य होगा, जिसका अर्थ है कि आपको सफलता पर एक ही वस्तु मिलेगी (क्योंकि निर्माता सहयोगी हैं), और असफलता होने पर समान अपवाद। कंस्ट्रक्टरों में से किसी में। मान लें कि आपने उपरोक्त श्रृंखला में एक S जोड़ा है (तो आप V से शुरू करते हैं और U से , T , और S को बारी से लगाकर S से समाप्त करते हैं), आपको या तो पहले S और T से , फिर U , से मिलता है। (एसटी) यू के अनुरूप , या यदि आपने पहली बार टी का उपयोग किया है , तो एस (टीयू) से संबंधित है। और यू का पीछा करते हैं , तोS । हालाँकि, यह केवल एक फैक्ट्री फ़ंक्शन में एक स्पष्ट तीन-गुना श्रृंखला लिखने के लिए स्पष्ट होगा।


क्या मैं सही तरीके से इकट्ठा कर रहा हूं कि एक को अभी भी कोशिश के साथ-साथ संसाधन का उपयोग करने की आवश्यकता है try (BufferedWriter writer = <BufferedWriter, FileWriter>createChainedResource(file)) { /* work with writer */ }?
एरिक

@ एरिक हाँ, आपको अभी भी कोशिश-के-संसाधनों का उपयोग करने की आवश्यकता होगी, लेकिन आपको केवल जंजीर संसाधन के लिए एक फ़ंक्शन का उपयोग करने की आवश्यकता होगी: फ़ैक्टरी फ़ंक्शन चैनिंग को एन्क्रिप्ट करता है। मैंने उपयोग का एक उदाहरण जोड़ा है; धन्यवाद!
निल्स वॉन बर्थ

2

चूँकि आपके संसाधन नेस्टेड हैं, आपकी कोशिश-क्लॉस भी होनी चाहिए:

try (FileWriter fw=new FileWriter(file)) {
    try (BufferedWriter bw=new BufferedWriter(fw)) {
        bw.write(text);
    } catch (IOException ex) {
        // handle ex
    }
} catch (IOException ex) {
    // handle ex
}

5
यह मेरे 2 उदाहरण के समान है। यदि कोई अपवाद नहीं होता है, तो FileWriter की closeदो बार कॉल की जाएगी।
Natix

0

मैं कहूंगा कि ARM का उपयोग न करें और क्लोजेबल के साथ चलें। जैसे विधि का उपयोग करें,

public void close(Closeable... closeables) {
    for (Closeable closeable: closeables) {
       try {
           closeable.close();
         } catch (IOException e) {
           // you can't much for this
          }
    }

}

इसके अलावा, आपको कॉल करने के बारे BufferedWriterमें विचार करना चाहिए क्योंकि यह न केवल पास को सौंप रहा है FileWriter, बल्कि यह कुछ सफाई भी करता है flushBuffer


0

मेरा समाधान एक "एक्स्ट्रेक्ट मेथड" रिफैक्टरिंग करना है, निम्नानुसार:

static AutoCloseable writeFileWriter(FileWriter fw, String txt) throws IOException{
    final BufferedWriter bw  = new BufferedWriter(fw);
    bw.write(txt);
    return new AutoCloseable(){

        @Override
        public void close() throws IOException {
            bw.flush();
        }

    };
}

printToFile या तो लिखा जा सकता है

static void printToFile(String text, File file) {
    try (FileWriter fw = new FileWriter(file)) {
        AutoCloseable w = writeFileWriter(fw, text);
        w.close();
    } catch (Exception ex) {
        // handle ex
    }
}

या

static void printToFile(String text, File file) {
    try (FileWriter fw = new FileWriter(file);
        AutoCloseable w = writeFileWriter(fw, text)){

    } catch (Exception ex) {
        // handle ex
    }
}

क्लास के लिबास डिजाइनरों के लिए, मैं उन्हें सुझाव दूंगा AutoClosableकि क्लोज़ को दबाने के लिए एक अतिरिक्त विधि के साथ इंटरफ़ेस का विस्तार करें । इस मामले में हम तब निकट व्यवहार को मैन्युअल रूप से नियंत्रित कर सकते हैं।

भाषा डिजाइनरों के लिए, सबक यह है कि एक नई सुविधा को जोड़ने का मतलब बहुत सारे लोगों को जोड़ना हो सकता है। इस जावा मामले में, जाहिर है कि एआरएम सुविधा संसाधन स्वामित्व हस्तांतरण तंत्र के साथ बेहतर काम करेगी।

अपडेट करें

मूल रूप से उपरोक्त कोड को फ़ंक्शन @SuppressWarningके BufferedWriterअंदर की आवश्यकता होती हैclose()

जैसा कि एक टिप्पणी द्वारा सुझाया गया है, अगर flush()लेखक को बंद करने से पहले बुलाया जाए , तो हमें returnकोशिश करनी चाहिए कि कोशिश ब्लॉक के अंदर किसी भी (अंतर्निहित या स्पष्ट) बयान से पहले की जाए । वर्तमान में ऐसा करने का कोई तरीका नहीं है कि मैं ऐसा करने वाले को यह सुनिश्चित करने के लिए कहूं, इसलिए इसके लिए दस्तावेज होना चाहिए writeFileWriter

अद्यतन रखें

उपरोक्त अद्यतन @SuppressWarningअनावश्यक बनाता है क्योंकि कॉल करने के लिए संसाधन को वापस करने के लिए फ़ंक्शन की आवश्यकता होती है, इसलिए स्वयं बंद होना आवश्यक नहीं है। दुर्भाग्य से, यह हमें स्थिति की शुरुआत में वापस ले जाता है: चेतावनी अब कॉलर पक्ष पर वापस ले जाया जाता है।

तो ठीक से इस को हल करने के लिए, हम एक अनुकूलित की जरूरत है AutoClosableकि जब भी यह बंद कर देता है, रेखांकन BufferedWriterकिया जाएगा flush()एड। दरअसल, यह हमें चेतावनी को दरकिनार करने का एक और तरीका दिखाता है, क्योंकि BufferWriterयह कभी भी किसी भी तरह से बंद नहीं होता है।


चेतावनी का अपना अर्थ है: क्या हम यहाँ यह सुनिश्चित कर सकते हैं कि bwवास्तव में tha डेटा लिखेंगे? यह बाद में बफ़र्ड होता है, इसलिए इसे केवल कभी-कभी डिस्क पर लिखना होता है (जब बफ़र पूर्ण और / या पर flush()और close()विधियाँ होती हैं)। मुझे लगता है कि flush()विधि को बुलाया जाना चाहिए। लेकिन फिर, बफर लेखक का उपयोग करने की कोई आवश्यकता नहीं है, वैसे भी, जब हम इसे एक बैच में तुरंत लिख रहे हैं। और यदि आप कोड को ठीक नहीं करते हैं, तो आप फ़ाइल को गलत क्रम में फ़ाइल में लिखे गए डेटा के साथ समाप्त कर सकते हैं, या फ़ाइल में बिल्कुल भी नहीं लिखा जा सकता है।
पेट्र जेनकॉक

यदि flush()कॉल करने की आवश्यकता है, तो यह तब होगा जब कॉल करने वाले को बंद करने का निर्णय लेने से पहले FileWriter। तो यह कोशिश ब्लॉक में printToFileकिसी भी returnएस से पहले होना चाहिए । यह एक हिस्सा नहीं होगा writeFileWriterऔर इस प्रकार यह चेतावनी उस फ़ंक्शन के अंदर कुछ भी नहीं है, लेकिन उस फ़ंक्शन का कॉलर है। यदि हमारे पास एक एनोटेशन है तो @LiftWarningToCaller("wanrningXXX")यह इस मामले और इसी तरह की मदद करेगा।
पृथ्वी इंजन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.