1. बाह्य संसाधने

Java प्रोग्राम चालत असताना, काहीवेळा तो Java मशीनच्या बाहेरील घटकांशी संवाद साधतो. उदाहरणार्थ, डिस्कवरील फायलींसह. या घटकांना सहसा बाह्य संसाधने म्हणतात. अंतर्गत संसाधने जावा मशीनमध्ये तयार केलेल्या वस्तू आहेत.

सामान्यतः, परस्परसंवाद या योजनेचे अनुसरण करतो:

रिसोर्सेस स्टेटमेंटसह प्रयत्न करा

ट्रॅकिंग संसाधने

ऑपरेटिंग सिस्टीम उपलब्ध संसाधनांचा काटेकोरपणे मागोवा ठेवते आणि विविध प्रोग्राम्समधून सामायिक प्रवेश नियंत्रित करते. उदाहरणार्थ, जर एखाद्या प्रोग्रामने फाइल बदलली, तर दुसरा प्रोग्राम ती फाइल बदलू शकत नाही (किंवा हटवू शकत नाही). हे तत्त्व फायलींपुरते मर्यादित नाही, परंतु ते सर्वात सहज समजण्यासारखे उदाहरण देतात.

ऑपरेटिंग सिस्टममध्ये फंक्शन्स (APIs) असतात जे प्रोग्रामला संसाधने प्राप्त करण्यास आणि/किंवा रिलीज करण्यास अनुमती देतात. जर एखादे संसाधन व्यस्त असेल तर केवळ तो मिळवलेला प्रोग्रामच त्याच्यासह कार्य करू शकतो. जर संसाधन विनामूल्य असेल तर कोणताही प्रोग्राम ते मिळवू शकतो.

कल्पना करा की तुमच्या ऑफिसमध्ये कॉफी मग शेअर केले आहेत. जर कोणी घोकंपट्टी घेतली तर इतर लोक ते घेऊ शकत नाहीत. पण एकदा का मग वापरला, धुऊन पुन्हा त्याच्या जागी ठेवला की तो परत कोणीही घेऊ शकतो. बस किंवा भुयारी मार्गावरील जागांची परिस्थिती सारखीच आहे. आसन फुकट असेल तर कोणीही घेऊ शकतो. जर एखादी जागा व्यापली असेल तर ती ज्याने घेतली असेल त्याच्याद्वारे ती नियंत्रित केली जाते.

बाह्य संसाधने मिळवणे .

प्रत्येक वेळी जेव्हा तुमचा Java प्रोग्राम डिस्कवरील फाइलसह कार्य करण्यास प्रारंभ करतो, तेव्हा Java मशीन ऑपरेटिंग सिस्टमला त्यात विशेष प्रवेशासाठी विचारते. जर संसाधन विनामूल्य असेल, तर Java मशीन ते मिळवते.

परंतु आपण फाईलसह कार्य पूर्ण केल्यानंतर, हे संसाधन (फाइल) सोडले जाणे आवश्यक आहे, म्हणजे आपल्याला ऑपरेटिंग सिस्टमला सूचित करणे आवश्यक आहे की आपल्याला यापुढे त्याची आवश्यकता नाही. तुम्ही असे न केल्यास, तुमच्या प्रोग्रामद्वारे संसाधन चालू राहील.

ऑपरेटिंग सिस्टम प्रत्येक चालू असलेल्या प्रोग्रामद्वारे व्यापलेल्या संसाधनांची सूची राखते. जर तुमचा प्रोग्राम नियुक्त संसाधन मर्यादा ओलांडत असेल, तर ऑपरेटिंग सिस्टम यापुढे तुम्हाला नवीन संसाधने देणार नाही.

चांगली बातमी अशी आहे की जर तुमचा प्रोग्राम संपुष्टात आला तर, सर्व संसाधने आपोआप रिलीझ होतील (ऑपरेटिंग सिस्टम स्वतःच हे करते).

वाईट बातमी अशी आहे की जर तुम्ही सर्व्हर ऍप्लिकेशन लिहित असाल (आणि बर्‍याच सर्व्हर ऍप्लिकेशन्स Java मध्ये लिहिलेले असतील), तर तुमचा सर्व्हर दिवस, आठवडे आणि महिने न थांबता चालण्यास सक्षम असणे आवश्यक आहे. आणि जर तुम्ही दिवसाला १०० फायली उघडल्या आणि त्या बंद केल्या नाहीत, तर काही आठवड्यांत तुमचा अर्ज त्याच्या संसाधन मर्यादेपर्यंत पोहोचेल आणि क्रॅश होईल. अनेक महिन्यांच्या स्थिर कामापेक्षा ते खूपच कमी आहे.


2. close()पद्धत

बाह्य संसाधनांचा वापर करणार्‍या वर्गांकडे त्यांना सोडण्याची एक विशेष पद्धत आहे: close().

खाली आम्ही एका प्रोग्रामचे उदाहरण देतो जो फाईलवर काहीतरी लिहितो आणि नंतर फाइल पूर्ण झाल्यावर ती बंद करतो, म्हणजेच ते ऑपरेटिंग सिस्टमचे स्त्रोत मोकळे करते. हे असे काहीतरी दिसते:

कोड नोंद
String path = "c:\\projects\\log.txt";
FileOutputStream output = new FileOutputStream(path);
output.write(1);
output.close();
फाईलचा मार्ग.
फाइल ऑब्जेक्ट मिळवा: संसाधन मिळवा.
फाइलवर लिहा
फाइल बंद करा - संसाधन सोडा

फाइल (किंवा इतर बाह्य संसाधने) सह कार्य केल्यानंतर, तुम्हाला close()बाह्य संसाधनाशी लिंक केलेल्या ऑब्जेक्टवर पद्धत कॉल करावी लागेल.

अपवाद

हे सर्व सोपे दिसते. परंतु प्रोग्राम चालत असताना अपवाद येऊ शकतात आणि बाह्य संसाधन सोडले जाणार नाही. आणि ते खूप वाईट आहे.

पद्धत नेहमी कॉल केली जाते याची खात्री करण्यासाठी , आम्हाला आमचा कोड - - close()ब्लॉकमध्ये गुंडाळणे आवश्यक आहे आणि ब्लॉकमध्ये पद्धत जोडणे आवश्यक आहे . हे असे काहीतरी दिसेल:trycatchfinallyclose()finally

try
{
   FileOutputStream output = new FileOutputStream(path);
   output.write(1);
   output.close();
}
catch (IOException e)
{
   e.printStackTrace();
}
finally
{
   output.close();
}

हा कोड संकलित होणार नाही, कारण outputव्हेरिएबल ब्लॉकमध्ये घोषित केले आहे try {}, आणि म्हणून ब्लॉकमध्ये दृश्यमान नाही finally.

चला ते दुरुस्त करूया:

FileOutputStream output = new FileOutputStream(path);

try
{
   output.write(1);
   output.close();
}
catch (IOException e)
{
   e.printStackTrace();
}
finally
{
   output.close();
}

हे ठीक आहे, परंतु ऑब्जेक्ट तयार करताना एखादी त्रुटी उद्भवल्यास ते कार्य करणार नाही FileOutputStreamआणि हे अगदी सहजपणे होऊ शकते.

चला ते दुरुस्त करूया:

FileOutputStream output = null;

try
{
   output = new FileOutputStream(path);
   output.write(1);
   output.close();
}
catch (IOException e)
{
   e.printStackTrace();
}
finally
{
   output.close();
}

अजूनही काही टीका आहेत. प्रथम, ऑब्जेक्ट तयार करताना त्रुटी आढळल्यास FileOutputStream, outputव्हेरिएबल शून्य होईल. ब्लॉकमध्ये ही शक्यता लक्षात घेतली पाहिजे finally.

दुसरे, close()पद्धत नेहमी ब्लॉकमध्ये म्हटले जाते finally, याचा अर्थ ब्लॉकमध्ये ते आवश्यक नसते try. अंतिम कोड असे दिसेल:

FileOutputStream output = null;

try
{
   output = new FileOutputStream(path);
   output.write(1);
}
catch (IOException e)
{
   e.printStackTrace();
}
finally
{
   if (output != null)
      output.close();
}

जरी आम्ही catchब्लॉक विचारात घेतला नाही, जो वगळला जाऊ शकतो, तर आमच्या कोडच्या 3 ओळी 10 बनतात. परंतु आम्ही मुळात फक्त फाइल उघडली आणि 1 लिहिली. जरा त्रासदायक, तुम्हाला वाटत नाही?


3. tryसंसाधनांसह

आणि इथे जावाच्या निर्मात्यांनी आमच्यावर काही सिंटॅक्टिक साखर शिंपडण्याचा निर्णय घेतला. त्याच्या 7 व्या आवृत्तीपासून सुरुवात करून, Java मध्ये नवीन try-with-resources स्टेटमेंट आहे.

हे पद्धतशीर अनिवार्य कॉलसह समस्येचे निराकरण करण्यासाठी अचूकपणे तयार केले गेले close(). सामान्य केस अगदी सोपे दिसते:

try (ClassName name = new ClassName())
{
     Code that works with the name variable
}

हे विधानाचे आणखी एक रूपांतर try आहे . तुम्हाला कीवर्ड नंतर कंस जोडणे आवश्यक आहे try, आणि नंतर कंसात बाह्य संसाधनांसह ऑब्जेक्ट्स तयार करा. कंसातील प्रत्येक ऑब्जेक्टसाठी, कंपाइलर मेथडमध्ये एक finallyविभाग आणि कॉल जोडतो close().

खाली दोन समतुल्य उदाहरणे आहेत:

लांब कोड संसाधनांसह प्रयत्न करा
FileOutputStream output = null;

try
{
   output = new FileOutputStream(path);
   output.write(1);
}
finally
{
   if (output != null)
   output.close();
}
try(FileOutputStream output = new FileOutputStream(path))
{
   output.write(1);
}

-with-resources वापरणारा कोड tryखूपच लहान आणि वाचायला सोपा आहे. आणि आमच्याकडे जितका कमी कोड असेल तितकी टायपो किंवा इतर त्रुटी होण्याची शक्यता कमी आहे.

तसे, आम्ही -with-resources स्टेटमेंटमध्ये जोडू catchआणि finallyब्लॉक करू शकतो try. किंवा त्यांची आवश्यकता नसल्यास तुम्ही त्यांना जोडू शकत नाही.



4. एकाच वेळी अनेक चल

तसे, जेव्हा आपल्याला एकाच वेळी अनेक फायली उघडण्याची आवश्यकता असते तेव्हा आपल्याला बर्‍याचदा परिस्थिती येऊ शकते. समजा तुम्ही फाइल कॉपी करत आहात, म्हणून तुम्हाला दोन ऑब्जेक्ट्सची आवश्यकता आहे: ज्या फाइलमधून तुम्ही डेटा कॉपी करत आहात आणि फाइल ज्यामध्ये तुम्ही डेटा कॉपी करत आहात.

या प्रकरणात, try-with-resources स्टेटमेंट तुम्हाला त्यात एक पण अनेक ऑब्जेक्ट्स तयार करू देते. ऑब्जेक्ट्स तयार करणारा कोड अर्धविरामांनी विभक्त केला पाहिजे. या विधानाचे सामान्य स्वरूप येथे आहे:

try (ClassName name = new ClassName(); ClassName2 name2 = new ClassName2())
{
   Code that works with the name and name2 variables
}

फायली कॉपी करण्याचे उदाहरण:

लांब कोड संक्षिप्त संकेत
String src = "c:\\projects\\log.txt";
String dest = "c:\\projects\\copy.txt";

FileInputStream input = null;
FileOutputStream output = null;

try
{
   input = new FileInputStream(src);
   output = new FileOutputStream(dest);

   byte[] buffer = input.readAllBytes();
   output.write(buffer);
}
finally
{
   if (input != null)
      input.close();
   if (output != null)
      output.close();
}
String src = "c:\\projects\\log.txt";
String dest = "c:\\projects\\copy.txt";

try(FileInputStream input = new FileInputStream(src);

FileOutputStream output = new FileOutputStream(dest))
{
   byte[] buffer = input.readAllBytes();
   output.write(buffer);
}

बरं, आम्ही इथे काय म्हणू शकतो? tryसंसाधनांसह ही एक अद्भुत गोष्ट आहे!


5. AutoCloseableइंटरफेस

पण एवढेच नाही. हे विधान कसे लागू केले जाऊ शकते यावर मर्यादा घालणार्‍या त्रुटींचा सजग वाचक त्वरित शोध सुरू करेल.

tryपण जर वर्गाकडे पद्धत नसेल तर -with-resources स्टेटमेंट कसे चालेल close()? बरं, समजा की काहीही बोलावणार नाही. कोणतीही पद्धत नाही, समस्या नाही.

tryपरंतु वर्गामध्ये अनेक close()पद्धती असल्यास -with-resources स्टेटमेंट कसे कार्य करते ? आणि त्यांच्याकडे जाण्यासाठी युक्तिवाद आवश्यक आहेत? close()आणि वर्गात पॅरामीटर्सशिवाय पद्धत नाही ?

मला आशा आहे की तुम्ही स्वतःला हे प्रश्न विचारले असतील आणि कदाचित इतरांनाही.

अशा समस्या टाळण्यासाठी, Java च्या निर्मात्यांनी , नावाचा एक विशेष इंटरफेस आणला आहे AutoCloseable, ज्याची फक्त एक पद्धत आहे — close(), ज्यामध्ये कोणतेही मापदंड नाहीत.

त्यांनी हे निर्बंध देखील जोडले की केवळ क्लासेसच्या ऑब्जेक्ट्सची अंमलबजावणी करणार्‍याAutoCloseable -सह-संसाधन विधानात संसाधन म्हणून घोषित केले जाऊ शकते try. परिणामी, अशा वस्तूंमध्ये नेहमी close()पॅरामीटर नसलेली पद्धत असते.

तसे, तुम्हाला असे वाटते का की try-with-resources स्टेटमेंटला रिसोर्स म्हणून घोषित करणे शक्य आहे असे ऑब्जेक्ट ज्याच्या क्लासची स्वतःची close()पद्धत पॅरामीटर्सशिवाय आहे परंतु जी लागू होत नाही AutoCloseable?

वाईट बातमी: योग्य उत्तर नाही आहे — वर्गांनी इंटरफेस लागू करणे आवश्यक आहे AutoCloseable.

चांगली बातमी: Java मध्ये बरेच वर्ग आहेत जे या इंटरफेसची अंमलबजावणी करतात, त्यामुळे सर्वकाही जसे पाहिजे तसे कार्य करेल अशी शक्यता आहे.