2015-03-17 8 views
9

java.nio.file.Files एपीआई पुरानी java.io.File कक्षा में वास्तव में एक अच्छा सुधार है, लेकिन एक विवरण मुझे अजीब के रूप में मारता है; delete() के अपवाद के साथ कोई विधि दस्तावेज नहीं है कि वे NoSuchFileException फेंक सकते हैं, और यहां तक ​​कि delete() कहता है कि यह वैकल्पिक है।क्या मुझे उम्मीद है कि फ़ाइलों में विधियों को NoSuchFileException फेंकने की उम्मीद है?

मैं गायब फाइलों और अन्य आईओ मुद्दों के कारण असफलताओं के बीच अंतर करने में सक्षम होना चाहता हूं, लेकिन ऐसा लगता है कि यह संभव होने की गारंटी नहीं है।

Files.exists() पर कॉल करने का विकल्प और जैसे ही दो संचालन के बीच फ़ाइल बनाई गई है, जैसे पहले से ही एक दौड़-स्थिति को जोखिम देता है।

क्या मुझे उम्मीद है कि Files में NoSuchFileException उचित हो सकता है? यदि हां, तो यह कहां दस्तावेज है? यदि नहीं, तो मैं लापता फ़ाइल के कारण विफलता को सुरक्षित रूप से कैसे निर्धारित कर सकता हूं?


उदाहरण: विंडोज 7 पर जावा 7.0.02 साथ Files.readAllLines() विधि एक NoSuchFileException बढ़ा है, हालांकि यह स्पष्ट रूप से ऐसा करने के लिए दस्तावेज नहीं कर रहा है:

Files.readAllLines(Paths.get("foo"), StandardCharsets.UTF_8) 
java.nio.file.NoSuchFileException: foo 
    at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79) 
    at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97) 
    at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102) 
    at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:229) 
    at java.nio.file.Files.newByteChannel(Files.java:315) 
    at java.nio.file.Files.newByteChannel(Files.java:361) 
    at java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:380) 
    at java.nio.file.Files.newInputStream(Files.java:106) 
    at java.nio.file.Files.newBufferedReader(Files.java:2660) 
    at java.nio.file.Files.readAllLines(Files.java:2993) 

उत्तर

0

फाइल क्लास दो हटाने विधियों प्रदान करता है।

हटाएं (पथ) विधि फ़ाइल को हटा देती है या हटाए जाने पर अपवाद फेंकता है। उदाहरण के लिए, यदि फ़ाइल मौजूद नहीं है तो NoSuchFileException फेंक दिया गया है। आप यह निर्धारित करने के लिए क्यों नष्ट इस प्रकार में विफल रहा है अपवाद पकड़ कर सकते हैं:

try { 
    Files.delete(path); 
} catch (NoSuchFileException x) { 
    System.err.format("%s: no such" + " file or directory%n", path); 
} catch (DirectoryNotEmptyException x) { 
    System.err.format("%s not empty%n", path); 
} catch (IOException x) { 
    // File permission problems are caught here. 
    System.err.println(x); 
} 

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

नोट:NoSuchFileException और DirectoryNotEmptyException नया जावा 7.

+0

मैं बाकी एपीआई के बारे में पूछ रहा हूं, न केवल 'हटाएं() '/' deleteIfExists() 'विधियों को हटाएं। बाकी एपीआई (उदा। 'ReadAllLines() ') दस्तावेज नहीं करता है कि यह' NoSuchFileException' उठाता है, भले ही ऐसा लगता है (कम से कम विंडोज़ पर)। यहां तक ​​कि 'हटाएं()' यह इंगित करता है कि यह एक वैकल्पिक अपवाद है, यह बताता है कि कॉलर्स इस व्यवहार पर भरोसा नहीं कर सकते हैं। – dimo414

1

सामान्य में में पेश अपवाद हैं: नहीं, तुम java.nio.file.Files में विश्वास तरीकों एक NoSuchFileException जब उम्मीद है, लेकिन आप सत्यापित कर सकते हैं फेंक नहीं कर सकते ।

जैसा कि आप स्टैकट्रैक से देख सकते हैं, Files फ़ाइल संचालन करने के लिए FileSystemProvider का उपयोग करता है। FileSystemProvider कार्यान्वयन प्रतिबंधित हैं (WindowsFileSystemProvider की तरह) और बदले में बहुत सारे मूल (सी) कोड का उपयोग करें। उदाहरण के लिए, मैंने NoSuchFileException को WindowsException पर देखा जो ERROR_FILE_NOT_FOUND या ERROR_PATH_NOT_FOUND की रिपोर्ट करने के लिए ऑपरेटिंग सिस्टम पर निर्भर करता है। एक और उदाहरण newInputStream मार्ग है जो ChannelInputStream से WindowsChannelFactory से WindowsNativeDispatcher.c पर जाता है जो अंत में देशी विंडोज फ़ंक्शन CreateFileW पर कॉल करता है।
केवल विंडोज के लिए शामिल कोड की मात्रा को देखते हुए, मुझे नहीं लगता कि इसे कैसे काम करने के लिए भरोसा किया जा सकता है उदाहरण के लिए लिनक्स जो here और here कोड का उपयोग करता है।

मेरे अनुभव में, लिनक्स (इसे POSIX) फाइल सिस्टम व्यवहार बहुत संगत है, लेकिन Windows (NT) फाइल सिस्टम व्यवहार नहीं है: मैं विंडोज के रूप में 8.

बिल्कुल वैसा ही व्यवहार करने के लिए विंडोज 7 मान नहीं होता अंत में, दौड़ की स्थिति के बारे में एक टिप्पणी: मुझे पता नहीं है कि कोई फ़ाइल सिस्टम मुझे गारंटी देता है कि निर्देशिका में सूचीबद्ध फाइलें वास्तव में मौजूद हैं (कुछ फ़ाइलों को पहले ही हटा दिया जा सकता है, खासकर जब एक ही निर्देशिका में फ़ाइलों पर चल रहे एकाधिक थ्रेड का उपयोग करते हैं)। पहले से ही Files.exists() जैसी विधियों का उपयोग करना, मेरे अनुभव में, एक बुरा विचार है जब तक कि आप बहुत सारे संसाधन आवंटित करने वाले नहीं हैं (उदाहरण के लिए फ़ाइल अपलोड करने के लिए कनेक्शन बनाना)। फ़ाइलों से निपटने के दौरान, यह मानना ​​बेहतर है कि सब कुछ क्रम में है और अपवादों को पकड़ें और फिर यह निर्धारित करने का प्रयास करें कि क्या गलत है। जैसे फ़ाइल पढ़ने पर, फ़ाइल को मौजूद होने पर जांचने के बिना इसे खोलें, और यदि आपको कोई त्रुटि मिलती है, तो जांचें कि फ़ाइल प्रारंभ करने के लिए मौजूद है या नहीं। यह बहुत से I/O संचालन को बचा सकता है जो बदले में प्रदर्शन में मदद करेगा।

+0

"यह मानना ​​बेहतर है कि सबकुछ क्रम में है और अपवादों को पकड़ें और फिर यह निर्धारित करने का प्रयास करें कि क्या गलत है।" निश्चित रूप से मैं सहमत हूं, और अंत में यह अच्छा होगा अगर 'फाइल' एपीआई ने अलग-अलग त्रुटि मामलों के लिए अलग-अलग अपवादों को स्पष्ट रूप से वापस कर दिया। – dimo414

+0

@ dimo414 यह अच्छा होगा लेकिन विषमताओं के साथ [इस तरह] (http://stackoverflow.com/q/12139482/3080094) (यदि आप केवल पढ़ने-योग्य विशेषता को हटाते हैं तो आप फ़ाइल को हटा सकते हैं) मैं नहीं हूं सुनिश्चित करें कि इसे प्लेटफार्मों में लगातार बनाया जा सकता है। – vanOekel

+0

सहमत हैं, किनारे के मामले हैं, लेकिन यह बहुत बुरा है कि सामान्य मामलों को अधिक स्पष्ट रूप से दस्तावेज नहीं किया गया है। ऐसा लगता है कि करने के लिए सबसे अच्छी बात यह है कि 'IOException' पकड़ें और फिर' Files.exists() 'की जांच करें, और' NoSuchFileException' की तलाश करने से परेशान न हों, भले ही इसे कभी-कभी फेंक दिया जा सके। – dimo414

संबंधित मुद्दे