"अमिगो, दहा-झोपडी!"

"मला जावा शिकून आनंद झाला, कॅप्टन!"

"निश्चिंतपणे, अमिगो. आज आमच्याकडे एक अतिशय मनोरंजक विषय आहे. आम्ही जावा प्रोग्राम बाह्य संसाधनांशी कसा संवाद साधतो याबद्दल बोलू आणि आम्ही एक अतिशय मनोरंजक जावा विधानाचा अभ्यास करू. तुमचे कान न झाकणे चांगले."

"मी सर्व कान आहे."

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

"मग अंतर्गत संसाधने काय मानली जातात?"

"अंतर्गत संसाधने ही Java मशीनमध्ये तयार केलेली वस्तू आहेत. सामान्यतः, परस्परसंवाद या योजनेचे अनुसरण करतात:

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

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

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

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

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

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

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

"ते न्याय्य वाटते."

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

"हे अशा प्रोग्रामसारखे आहे जे सर्व मेमरी खाऊ शकतात ..."

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

"जर ती चांगली बातमी असेल तर याचा अर्थ वाईट बातमी आहे का?"

"तंतोतंत तसे. वाईट बातमी अशी आहे की जर तुम्ही सर्व्हर ऍप्लिकेशन लिहित असाल तर..."

"पण मी असे अर्ज लिहितो का?"

"जावामध्ये बर्‍याच सर्व्हर ऍप्लिकेशन्स लिहिलेल्या आहेत, त्यामुळे बहुधा तुम्ही ते कामासाठी लिहाल. मी म्हटल्याप्रमाणे, जर तुम्ही सर्व्हर ऍप्लिकेशन लिहित असाल, तर तुमच्या सर्व्हरला दिवस, आठवडे, महिने नॉन-स्टॉप चालवणे आवश्यक आहे. इ.

"दुसर्‍या शब्दात, प्रोग्राम समाप्त होत नाही आणि याचा अर्थ मेमरी आपोआप रिलीझ होत नाही."

"अगदी. आणि जर तुम्ही दिवसाला १०० फाईल्स उघडल्या आणि त्या बंद केल्या नाहीत, तर काही आठवड्यांत तुमचा अर्ज त्याच्या संसाधन मर्यादेपर्यंत पोहोचेल आणि क्रॅश होईल."

"हे स्थिर कामासाठी अनेक महिने कमी पडत आहे! काय करता येईल?"

"बाह्य संसाधने वापरणारे वर्ग त्यांना सोडण्यासाठी एक विशेष पद्धत आहे: 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 लिहिले."

"अरे... प्रकरणाचा निष्कर्ष काढणे ही चांगली गोष्ट आहे. तुलनेने समजण्यासारखे आहे, परंतु काहीसे कंटाळवाणे आहे, नाही का?"

"म्हणूनच आहे. म्हणूनच जावाच्या निर्मात्यांनी काही सिंटॅक्टिक साखर जोडून आम्हाला मदत केली. आता प्रोग्रामच्या हायलाइटकडे जाऊया, किंवा त्याऐवजी, हा धडा:

try- संसाधनांसह

"त्याच्या 7 व्या आवृत्तीपासून सुरुवात करून, Java मध्ये नवीन try-with-sources स्टेटमेंट आहे.

"पद्धतीवर अनिवार्य कॉलसह समस्येचे निराकरण करण्यासाठी ते अचूकपणे तयार केले गेले होते 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. किंवा त्यांची गरज नसल्यास तुम्ही त्यांना जोडू शकत नाही.

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

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

"या प्रकरणात, 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";

try(FileInputStream input = new FileInputStream(src);

FileOutputStream output = new FileOutputStream(dest))
{
   byte[] buffer = input.readAllBytes();
   output.write(buffer);
}
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();
}

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

"आपण काय म्हणू शकतो की आपण ते वापरावे."