समारोह कर सकते हैं एक FileNotFoundException के माध्यम से है, लेकिन मैं इस बुला और फिर एक कोशिश पकड़ के आधार पर कुछ कर की तरह महसूस बुरा व्यवहार है।
मैं असहमत हूं। आईएमओ, यह परीक्षण कर रहा है अगर फाइल खोलने से पहले मौजूद है तो यह खराब अभ्यास है।
File f = new File("someFile");
InputStream is;
संस्करण # 1
if (f.exists()) {
is = new FileInputStream(f);
...
} else {
System.err.println("Doesn't exist");
}
संस्करण # 2
try {
is = new FileInputStream(f);
...
} catch (FileNotFoundException ex) {
System.err.println("Doesn't exist");
}
वहाँ पहले संस्करण के साथ समस्याओं का एक नंबर:
कोड के इन दो संस्करणों की तुलना करें
संस्करण # 1 एक अतिरिक्त सिस्ट बनाता है जब आप f.exists()
पर कॉल करते हैं तो कॉल करें। इससे पहले संस्करण को औसत पर धीमा कर दिया जाता है, जब तक कि उच्च संभावना नहीं है कि फ़ाइल मौजूद नहीं होगी।
संस्करण # 1 में दौड़ की स्थिति है। अगर कुछ बाहरी प्रक्रिया लगभग एक ही समय में फ़ाइल को हटा देती है, तो आप file.exists()
के साथ सत्य लौट सकते हैं, और फिर FileInputStream
कन्स्ट्रक्टर फेंकने FileNotFoundException
पर समाप्त हो सकता है। यह ऐसी दौड़ की स्थिति है जिसका उपयोग सुरक्षा को तोड़ने के लिए किया जा सकता है यदि प्रश्न में फ़ाइल सुरक्षा महत्वपूर्ण है। (वास्तव में, वहाँ एक दूसरी रेस शर्त भी है, जहां फ़ाइल बनाया जा रहा है और file.exists()
रिटर्न झूठी जब बाद में एक प्रयास को खोलने के लिए यह सफल होता है। लेकिन उस रेस स्थिति शायद हानिरहित है।)
एक और समस्या यह है कि FileInputStream
को IOException
फेंकने के रूप में घोषित किया गया है। यह देखने के लिए परीक्षण करना कि फ़ाइल मौजूद है, केवल संभावित विफलता मोड में से एक के साथ सौदा करती है। आपका कोड उन अन्य IOException
वैसे भी पकड़ने और उससे निपटने के लिए होगा।
@Pieces टिप्पणी की:
अपवाद है जब कुछ वास्तव में गलत आप कोई नियंत्रण नहीं है कि हो जाता है के लिए किया जाना चाहिए। इस मामले में, मेरा पूरा नियंत्रण है।
असल में, आपके पास इसका पूर्ण नियंत्रण नहीं है। निश्चित रूप से सामान्य मामले में नहीं। यहां तक कि आपके विशेष उपयोग मामले में, सिद्धांत की स्थिति अभी भी संभव है।
लेकिन सोचने की इस पंक्ति के साथ वास्तविक समस्या यह है कि आप परिस्थितियों में अपवादों से बचने के लिए हुप्स के माध्यम से कूदते हैं जहां अपवाद/अपवाद हैंडलिंग सर्वोत्तम समाधान है। यह कोड को अधिक जटिल, कम पठनीय, और संभावित रूप से धीमा और/या अधिक नाजुक बनाता है।
सामान्य हठधर्मिता इस प्रकार है:
"अपवाद केवल असाधारण स्थितियों में इस्तेमाल किया जाना चाहिए"।
यह वही नहीं है जैसा आपने कहा था। "असाधारण" शब्द का अर्थ वास्तव में "सामान्य नहीं" है। इसका "बहुत कुछ गलत हो जाता है जिस पर आपका कोई नियंत्रण नहीं है" की तुलना में इसका व्यापक अर्थ है।
मैं इस प्रकार हठधर्मिता पर विस्तार के लिए करते हैं:
अपवाद नहीं सामान्य प्रवाह नियंत्रण के लिए इस्तेमाल किया जाना चाहिए।
अपवाद अगर वे भी महंगा पर औसत साबित करने के लिए जा रहे हैं नहीं इस्तेमाल किया जाना चाहिए।
अपवाद का उपयोग किया जाना चाहिए यदि आप उन परीक्षणों से बचने के लिए उपयोग करेंगे जो विश्वसनीय नहीं हैं।
अपवाद यदि परीक्षण आप उन्हें बचने के लिए प्रयोग करेंगे इस्तेमाल किया जाना चाहिए बहुत महंगा पर औसत हैं।
अपवाद का उपयोग किया जाना चाहिए यदि वे आपके कोड को काफी सरल बनाते हैं (ऊपर मॉड्यूलो)। और सादगी के लिए मानदंड यह है कि कोड औसत जावा प्रोग्रामर द्वारा पठनीय है या नहीं।
(नोट - और "औसतन" "भी महंगा" ...)
अब शाम होने तक के बारे में कैसे असाधारण एक घटना होने की जरूरत है आने बहस कर सकते हैं, लेकिन मेरा लेना यह है कि यह वास्तव में औसत प्रदर्शन लागत (संदर्भ में) बनाम दृष्टिकोण (संदर्भ में) की सापेक्ष सादगी को संतुलित करने का विषय है। कोई भी विडंबनात्मक नियम जो ट्रेड-ऑफ और संदर्भ के लिए जिम्मेदार नहीं है, कुछ मामलों में आपको नुकसान पहुंचाएगा।
नोट: इस तरह से File.exists() का उपयोग करना 1) सभी अपवादों के खिलाफ सुरक्षा नहीं करता है, 2) आपको दौड़ की स्थिति के लिए खुलता है, और 3) आपको औसत पर धीमा प्रोग्राम बनाता है ... जब तक कि मौजूद नहीं है एक * संभावित * परिदृश्य हैं। –
मैं पहली विधि पसंद करता हूं, क्योंकि यह अस्पष्टता रखता है कि फ़ाइल वास्तव में – njzk2