2016-03-25 10 views
19

जब मुझे File file = new File("e:/"); कोड के साथ java.lang.File क्लास मिला, तो निश्चित रूप से मुझे एक फ़ाइल क्लास ई: \ निर्देशिका का प्रतिनिधित्व करता है।क्या यह जावा jdk में एक बग है?

लेकिन अगर मुझे कोड File file = new File("e:"); कोड के साथ फ़ाइल क्लास मिला है और मैं बस ड्राइव ई में हूं, तो मुझे एक फ़ाइल क्लास वर्तमान निर्देशिका का प्रतिनिधित्व करता है।

मान लें कि मैं निर्देशिका में हूं E: \ dir \, और इस निर्देशिका में test.java नाम की एक फ़ाइल है। यह सामग्री है:

import java.io.File; 
public class Test { 
    public static void main(String[] args) { 
     File file = new File("e:"); 
     File[] files = file.listFiles(); 
     for(File f: files){ 
      System.out.println(f + " " + f.exists()); 
     } 
    } 
} 

ओपन cmd उपकरण और करने के लिए निर्देशिका ई नेविगेट: \ dir, उस में निम्न आदेश निष्पादित करें:

E:\dir> javac Test.java 
E:\dir> java Test 

मुझे मिल गया:

e:\Test.class false 
e:\Test.java false 

क्या यह एक जावा जेडीके बग है?


@JimGarrison से अतिरिक्त जानकारी:

मैं इस कोड

public class Foo3 
{ 
    public static void main(String[] args) throws Exception 
    { 
     File f = new File("D:"); 
     System.out.println(f.getCanonicalPath()); 
     for (File x : f.listFiles()) 
      System.out.println(x + " " + x.getCanonicalPath() + " " + x.getAbsolutePath() + " " + x.exists() + " " + x.getAbsoluteFile().exists()); 
    } 
} 
ग्रहण (जो मेरे डी पर रहता है: ड्राइव) में

भाग गया और निम्न उत्पादन मिल गया:

D:\dev\src\pdxep 
D:\.classpath D:\dev\src\pdxep\.classpath D:\dev\src\pdxep\.classpath false true 
D:\.project D:\dev\src\pdxep\.project D:\dev\src\pdxep\.project false true 
D:\.settings D:\dev\src\pdxep\.settings D:\dev\src\pdxep\.settings false true 
D:\gallery D:\dev\src\pdxep\gallery D:\dev\src\pdxep\gallery false true 
D:\pom.xml D:\dev\src\pdxep\pom.xml D:\dev\src\pdxep\pom.xml false true 
D:\src D:\dev\src\pdxep\src D:\dev\src\pdxep\src false true 
D:\target D:\dev\src\pdxep\target D:\dev\src\pdxep\target false true 

जो पुष्टि करता है कि कुछ मजाकिया चल रहा है।

जावा Bug 8130462 संबंधित प्रतीत होता है क्योंकि इसे विशेष रूप से विंडोज़ में सापेक्ष बनाम पूर्ण पथ के साथ करना है।

+1

बहुत उत्सुक। मैं भी समस्या को पुन: पेश कर सकता हूं। –

+0

मैंने ऊपर लिखा गया प्रोग्राम चलाया (हालांकि मैंने क्लास नाम को टेस्टफाइल में संशोधित किया), और ई: ड्राइव (विंडोज 10) के लिए अपेक्षित आउटपुट (फाइलें और निर्देशिका सूचीबद्ध, इत्यादि) प्राप्त की। जावा 1.8.0_72 चल रहा है। @JimGarrison यह दिलचस्प है कि आपने इस मुद्दे को पुन: उत्पन्न किया। ग्रहण और कमांड लाइन पर दोनों इसे चलाएं। केवल अंतर यह है कि मेरे पास पैकेज नाम था इसलिए यह जावा-सीपी ./bin पैकेज था। टेस्टफाइल – KevinO

+0

यदि आप डीबगर में भागते हैं और 'println' पर रुकते हैं तो आप देख सकते हैं कि पथ और कैननिकल पथ के बीच कोई अंतर है। आपके द्वारा देखे जाने वाले आउटपुट (वर्तमान निर्देशिका को याद करना) फ़ाइल की तलाश करने के लिए उपयोग किया जाता है, लेकिन कैननिकल पथ को प्रिंट करने से वर्तमान निर्देशिका शामिल होती है। निश्चित रूप से एक बग की तरह दिखता है (संभवतः विंडोज फाइल सिस्टम प्रदाता के कार्यान्वयन में)। एक स्पष्ट पूर्ण पथ स्ट्रिंग से फ़ाइल बनाना इस समस्या में नहीं है। –

उत्तर

1

File प्राप्त करने के बारे में पहला भाग कोड File file = new File("e:"); के साथ वर्तमान कार्य निर्देशिका का प्रतिनिधित्व करने वाला पहला भाग एक बग नहीं है। यह एक विंडोज़ "ड्राइव सापेक्ष पथ" है। यही है, निर्दिष्ट ड्राइव में वर्तमान कार्य निर्देशिका से संबंधित एक पथ है। (हाँ, विंडोज ड्राइव प्रति एक अलग काम कर रहे निर्देशक है)

मुद्दा यह है कि जावा गलत तरीके से रास्ते में ड्राइव अक्षर जो बनाता है एक निरपेक्ष पथ की तरह पथ नज़र के बाद एक \ कहते है, और गलत तरीके से शायद file.exists() पर false रिटर्न उसके कारण।

हालांकि, जावा सही ढंग से कैननिकल-पथ और पूर्ण पथ को हल करता है और सही ढंग से x.getAbsoluteFile().exists() पर सही लौटाता है। जैसा कि आपने अपने उदाहरण कोड में देखा है, जावा file.listFiles() में CWD की सामग्री को सही ढंग से देता है।

मुझे डेटाबेस में पुरानी बग मिली जो JDK-5066567 इस बारे में या कम से कम इसी तरह के समान है। यह 2004 में बनाया गया था और "प्रगति में" 2013 पर सेट किया गया था और वर्तमान Assignee "निष्क्रिय" है इसलिए मुझे नहीं लगता कि हम जल्द ही इसके लिए कोई फिक्स देखेंगे।

तो आपसे सवाल करने के लिए, मैं हाँ कहूंगा, यह एक बग है।

हालांकि, ऐसा लगता है कि java.nio.file.Path में इसे बेहतर तरीके से संभाला जाता है। इसलिए यदि आपके उपयोग के मामले में java.nio.file.* पैकेज का उपयोग करना संभव है, तो यह स्वीकार्य कामकाज हो सकता है।

1

यह एक बग नहीं है।

  • E:/ मतलब है कि आप दोनों एक ड्राइव और एक निर्देशिका

  • E: मतलब है कि आप केवल एक ड्राइव निर्दिष्ट निर्दिष्ट करते हैं, निर्देशिका डिफ़ॉल्ट मान पर छोड़ दिया है।

नोट: अब लोगों के रूप में वर्तमान निर्देशिका वास्तव में है डिफ़ॉल्ट निर्देशिका की क्या सोचते हैं। यानी जब कोई निर्दिष्ट नहीं किया जाता है तो डिफ़ॉल्ट रूप से क्या लागू होता है। यह वही है यदि आप ड्राइव निर्दिष्ट नहीं करते हैं, तो डिफ़ॉल्ट (वर्तमान डिफ़ॉल्ट) लागू होगा।

यह अधिकांश फाइल सिस्टम पर काम करता है।

+0

डिफ़ॉल्ट निर्देशिका के बारे में दिलचस्प, यह नहीं पता था। क्या आप इसके बारे में अधिक पढ़ने के लिए एक लिंक प्रदान कर सकते हैं। हालांकि, file.exists() को इस पर ध्यान दिए बिना अभी भी सच होना चाहिए, और यह बग है, इसलिए मुझे खेद है, लेकिन उस संबंध में मुझे लगता है कि आप गलत हैं। या क्या आपके पास इस व्यवहार का स्पष्टीकरण है? – gustf

+0

'वर्तमान कार्यशील निर्देशिका' दशकों तक उपयोग में शब्द रही है, और यही कारण है कि उदाहरण के लिए 'pwd' कमांड' pdd' वर्तनी नहीं है। अब नाम बदलने की कोशिश में ज्यादा बात नहीं है। – EJP

+0

@EJP, तो हो सकता है कि आप समझा सकें कि आदरणीय वीएमएस की कमांड भाषा (जिसे डीसीएल कहा जाता है) में, सीडी कमांड वास्तव में 'डिफ़ॉल्ट सेट' है। और बीटीडब्लू, क्या मुझे आपको याद दिलाने की ज़रूरत है कि विंडोज के मुख्य वास्तुकार डेव कटलर थे, जो वीएमएस के वास्तुकार भी थे? –

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