सवाल क्या मैं Java 7 का उपयोग कर संसाधनों के साथ सही तरीके से उपयोग कर रहा हूं


मैं बफर किए गए पाठक और फ़ाइल रीडर को बंद करने की उम्मीद कर रहा हूं और अपवाद फेंकने पर संसाधन जारी किए गए हैं।

public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
    try (BufferedReader br = new BufferedReader(new FileReader(filePath)))
    {
        return read(br);
    } 
}

हालांकि, क्या एक आवश्यकता है catch सफल बंद करने के लिए खंड?

संपादित करें:

अनिवार्य रूप से, जावा 7 के लिए नीचे दिए गए जावा 7 में उपरोक्त कोड है:

public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{

    BufferedReader br = null;

    try
    {
        br = new BufferedReader(new FileReader(filePath));

        return read(br);
    }
    catch (Exception ex)
    {
        throw ex;
    }
    finally
    {
        try
        {
            if (br != null) br.close();
        }
        catch(Exception ex)
        {
        }
    }

    return null;
}

76
2017-07-15 09:32


मूल


फिर से अपना प्रश्न पढ़ने के बाद, मुझे यकीन नहीं है कि मैं इसे अच्छी तरह समझता हूं। क्या आप इसे समझा सकते हैं? - Maroun
नमस्ते। चीता, मैं पहले की भूमिका को समझने की कोशिश कर रहा हूं catch जावा 6 के लिए आपके उदाहरण का। आईई। catch (Exception ex) { throw ex; } - यह अपवाद को फिर से फेंक रहा है, यह कुछ भी नहीं कर रहा है, इसे किसी भी चोट के बिना आसानी से हटाया जा सकता है। या क्या मैं कुछ न कुछ भूल रहा हूं? - Sasha
आपके वाक्यविन्यास के बारे में कुछ भी गलत नहीं है। यदि आप संसाधनों के साथ प्रयासों के बारे में अधिक जानना चाहते हैं, तो इस आलेख को देखें: जावा संसाधनों के साथ प्रयास करें - Hussein Terek


जवाब:


यह सही है और इसके लिए कोई आवश्यकता नहीं है catch खंड। ओरेकल जावा 7 डॉक्टर का कहना है कि संसाधन बंद हो जाएगा परवाह किए बिना क्या एक अपवाद वास्तव में फेंक दिया गया है या नहीं।

आपको एक का उपयोग करना चाहिए catch खंड केवल तभी जब आप अपवाद पर प्रतिक्रिया करना चाहते हैं। catch खंड निष्पादित किया जाएगा बाद संसाधन बंद है।

यहां से एक स्निपेट है ओरेकल का ट्यूटोरियल:

निम्न उदाहरण फ़ाइल से पहली पंक्ति पढ़ता है। यह एक का उपयोग करता है   फ़ाइल से डेटा पढ़ने के लिए BufferedReader का उदाहरण। BufferedReader   एक संसाधन है जो प्रोग्राम समाप्त होने के बाद बंद होना चाहिए   यह:

static String readFirstLineFromFile(String path) throws IOException {
    try (BufferedReader br =
                   new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }
} // In this example, the resource declared in the try-with-resources statement is a BufferedReader.

... क्योंकि BufferedReader इंस्टेंस में घोषित किया गया है   संसाधन के साथ प्रयास करें, चाहे यह परवाह किए बिना बंद हो जाएगा   कोशिश कथन सामान्य या अचानक समाप्त होता है (जिसके परिणामस्वरूप   विधि IufException फेंकने BufferedReader.readLine)।

संपादित करें

नए संपादित प्रश्न के बारे में:

जावा 6 में कोड निष्पादित करता है catch और बाद में finally ब्लॉक। इससे संसाधनों को अभी भी संभावित रूप से खोला जा सकता है catch ब्लॉक।

जावा 7 वाक्यविन्यास में, संसाधन बंद हैं से पहले  catch ब्लॉक, इसलिए संसाधन पहले से ही बंद कर दिए गए हैं catch ब्लॉक निष्पादन। यह उपरोक्त लिंक में दस्तावेज है:

संसाधनों के साथ-साथ कथन में, किसी भी पकड़ या अंत में ब्लॉक चलाया जाता है   घोषित संसाधनों के बंद होने के बाद।


94
2017-07-15 09:40





इस विशेष मामले में आपके संसाधनों का उपयोग ठीक से काम करेगा, लेकिन यह सामान्य रूप से बिल्कुल सही नहीं है। आपको चेन संसाधनों को इस तरह नहीं करना चाहिए क्योंकि इससे अप्रिय आश्चर्य हो सकता है। मान लें कि आपके पास एक वेरिएबल बफर आकार है:

public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
    int sz = /* get buffer size somehow */
    try (BufferedReader br = new BufferedReader(new FileReader(filePath), sz))
    {
        return read(br);
    } 
}

मान लें कि कुछ गलत हो गया है और आप समाप्त हो गए हैं sz नकारात्मक होना इस मामले में आपका फ़ाइल संसाधन (के माध्यम से बनाया गया new FileReader(filePath)) मर्जी नहीं बंद रहा।

इस समस्या से बचने के लिए आपको प्रत्येक संसाधन को अलग से निर्दिष्ट करना चाहिए:

public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
    int sz = /* get buffer size somehow */
    try (FileReader file = new FileReader(filePath);
         BufferedReader br = new BufferedReader(file, sz))
    {
        return read(br);
    } 
}

इस मामले में भी अगर प्रारंभिक br विफल रहता है file अभी भी बंद हो जाता है। आप अधिक जानकारी प्राप्त कर सकते हैं यहाँ तथा यहाँ


65
2018-01-25 09:37



मैं समझने की कोशिश कर रहा हूं कि संसाधन किस प्रकार बनाया गया है new FileReader(filePath)) मामले में बंद नहीं होगा IllegalArgumentException एसजे नकारात्मक होने पर फेंक दिया जाता है। कोशिश-के-संसाधन सभी बंद नहीं करते हैं AutoClosable किसी भी अपवाद के बावजूद संसाधन? - Prasoon Joshi
@P्रासoonJoshi नहीं, यह केवल कॉल करता है .close() उन चर के लिए जिन्हें संसाधन-संसाधन प्रारंभकर्ता में घोषित किया गया है। यही कारण है कि इस उदाहरण में इसे दो घोषणाओं में विभाजित करना चाल है। - Mario Carneiro
एंड्री और @ मारियो आप दोनों सही और गलत हैं। पहले उदाहरण में, FileReader को प्रयास-संसाधन-संसाधन तर्क द्वारा बंद नहीं किया गया है। लेकिन जब BufferedReader बंद हो जाता है, तो यह लपेटा गया FileReader भी बंद कर देगा। सबूत के लिए, java.io.BufferedReader.close () के स्रोत पर नज़र डालें। नतीजतन, पहले उदाहरण से कोड पसंद किया जाना चाहिए, क्योंकि यह अधिक संक्षिप्त है। - jschreiner
@jschreiner सच है, हालांकि एंड्री (कुछ हद तक योगदान) मुद्दा जिसमें sz < 0 निर्माता को अपवाद फेंकने का कारण बनता है वास्तव में संसाधन रिसाव का कारण बनता है। - Mario Carneiro
@ मारियो मैं सहमत हूं। बाहरी कन्स्ट्रक्टर असफल हो सकता है, और आंतरिक संसाधन लीक हो जाएगा। मैंने पहले यह नहीं देखा, धन्यवाद। - jschreiner