2016-12-22 5 views
6

मैं वर्तमान में कुछ पथ ट्रैवर्सल से संबंधित सुरक्षा तंत्र में जांच कर रहा हूं और java.io.File.getCanonicalPath() के अजीब व्यवहार में आया हूं। मैंने सोचा कि CanonicalPath हमेशा सार अंतर्निहित फ़ाइल के सही अद्वितीय पथ का प्रतिनिधित्व करेगा। हालांकि अगर फ़ाइल नाम में दो बिंदुओं के बाद एक स्थान होता है तो कैननिकलपैथ अब सही पथ का प्रतिनिधित्व नहीं कर रहा है।जावा फ़ाइल कैनोनिकलपैथ पूंछ '..' के साथ असंगत व्यवहार की ओर जाता है

यहाँ उदाहरण है:

File root = new File("c:/git/"); 
String relative = ".. /.. \\"; 
File concatFile = new File (root.getCanonicalPath(), relative); 

System.out.println("ConcatFileAbsolute: '" + concatFile.getAbsolutePath() + "'"); 
System.out.println("ConcatFileCanonical: '" + concatFile.getCanonicalPath() + "'"); 

File canonFile = new File(concatFile.getCanonicalPath()); 
System.out.println("\ncanonFileCanonical: '" + canonFile.getCanonicalPath() + "'"); 
System.out.println("canonFileAbsolute: '" + canonFile.getAbsolutePath() + "'"); 
System.out.println("canonFileName: '" + canonFile.getName() + "'\n"); 

for (File file : canonFile.listFiles()) { 
    System.out.println("canon: '" + file.getCanonicalPath() + "' - absolute: '" + file.getAbsolutePath()+ "'"); 
} 

कंसोल आउटपुट:

ConcatFileAbsolute: 'C:\git\.. \.. ' 
ConcatFileCanonical: 'C:\git\.. \' 

canonFileCanonical: 'C:\git\' 
canonFileAbsolute: 'C:\git\.. ' 
canonFileName: '.. ' 

canon: 'C:\git\.. \$Recycle.Bin' - absolute: 'C:\git\.. \$Recycle.Bin' 
canon: 'C:\git\.. \.m2' - absolute: 'C:\git\.. \.m2' 
canon: 'C:\git\.. \boot' - absolute: 'C:\git\.. \boot' 
...other content of C:/ 

आप देख सकते हैं, हालांकि canonFile की canonicalPath स्पष्ट रूप से इंगित यह सी में स्थान दिया गया है: \ Git \, लेकिन .listFiles सूचियों सी में सभी फाइलें:।

यह केवल तब होता है जब मैं नई फ़ाइल (स्ट्रिंग, स्ट्रिंग) कन्स्ट्रक्टर का उपयोग करता हूं। अगर मैं फ़ाइल को concatFile = नई फ़ाइल (root.getCanonicalPath() + रिश्तेदार) में तीसरी पंक्ति बदलता हूं; तो आउटपुट के रूप में की उम्मीद है:

ConcatFileAbsolute: 'C:\git.. \.. ' 
ConcatFileCanonical: 'C:\git\' 
- The following output then lists files under C:\git\ 

यदि इस व्यवहार यूनिक्स सिस्टम पर इसी तरह की है मैं नहीं जानता।

क्या कोई इस व्यवहार को स्पष्ट कर सकता है? क्या इसका इरादा है?

धन्यवाद अग्रिम!

+0

आपको अपने प्रश्न का कुछ जोड़ने के लिए, प्रश्न को संपादित चाहते हैं, कोड:

Dim folderName folderName = "c:\temp\.. " Dim fso Set fso = CreateObject("Scripting.FileSystemObject") Dim fullpath fullpath = fso.GetAbsolutePathName(folderName) WScript.Echo "fullpath: " & fullpath 

यह बिल्कुल वैसा ही परिणाम देता है टिप्पणियों में काफी हद तक अपठनीय है। – pvg

उत्तर

3

बधाई हो! आपको WinAPI का एक संभावित बग (या सुविधा?) मिली है।

अधिक विशेष रूप से, आपके सवाल कोड की एक पंक्ति को कम किया जा सकता है:

क्यों new File("c:\\temp\\.. ").getCanonicalPath() रिटर्न c:\temp\ बजाय c:\?

संक्षिप्त उत्तर: .. के बाद पूंछ की जगह के कारण (हाँ, आपने इसका उल्लेख किया है)।

लांग जवाब: अगर हम अंतर्निहित वर्ग के जावा कार्यान्वयन के अंदर दिखेगा, हमने पाया होगा कि विंडोज के लिए यह WinNTFileSystem वर्ग है, जहां देशी विधि canonicalize0("c:\\temp\\.. ") इस टूटे हुए मान देता है। क्यूं कर? यह परीक्षण करने के लिए मैं जीत एपीआई परीक्षण करने के लिए सरल VBS कोड लिखा है:

fullpath: C:\temp 
+0

क्या उस कॉल पर कोई त्रुटि रिपोर्टिंग है? '.. 'एक फ़ाइल नाम की तरह दिखता है, एपीआई सिर्फ इसे अमान्य के रूप में टॉस करने का निर्णय ले सकता है। किसी भी तरह से 'c: \' वापस नहीं लौटने का तरीका पूरी तरह से अनुचित नहीं लगता है। – pvg

+0

बहुत बहुत धन्यवाद। यह कम से कम ओएस स्तर के बारे में बताता है! मैंने java.io.File (कंस्ट्रक्टर के साथ-साथ getCanonicalPath) के कार्यान्वयन को देखा और आप सही हैं। Canonicalize और संकल्प के fs- विशिष्ट कार्यान्वयन समस्या प्रतीत होता है। – guitarlum

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