2009-05-01 6 views
39

डायरेक्टरी वॉकर क्लास में मैं यह जानना चाहता हूं कि फ़ाइल फ़ाइल वास्तव में निर्देशिका के लिए एक प्रतीकात्मक लिंक है (मानते हुए, वॉकर यूनिक्स सिस्टम पर चलता है)। दिया गया है, मुझे पहले से ही पता है कि उदाहरण एक निर्देशिका है, क्या प्रतीकात्मक लिंक निर्धारित करने के लिए निम्नलिखित विश्वसनीय स्थिति होगी?जावा 1.6 - प्रतीकात्मक लिंक

File file; 
// ...  
if (file.getAbsolutePath().equals(file.getCanonicalPath())) { 
    // real directory ---> do normal stuff  
} 
else { 
    // possible symbolic link ---> do link stuff 
} 
+0

http://stackoverflow.com/questions/2175673/java-check-symbolic-link-file-existence – Gray

+6

जावा 1.7: [java.nio.Files.isSymbolicLink (पथ)] से संबंधित (http: // docs .oracle.com/javase/7/docs/api/java/nio/file/files.html # isSymbolicLink% 28java.nio.file.Path% 29) - मेरे लिए एक नोट - मैं यहां वापस समाप्त रहता हूं! –

उत्तर

45

अपाचे कॉमन्स में उपयोग की जाने वाली तकनीक मूल निर्देशिका के लिए कैननिकल पथ का उपयोग करती है, न कि फाइल स्वयं। मुझे नहीं लगता कि आप गारंटी दे सकते हैं कि एक विसंगति एक प्रतीकात्मक लिंक के कारण है, लेकिन यह एक अच्छा संकेत है कि फ़ाइल को विशेष उपचार की आवश्यकता है।

यह Apache code (their license के अधीन), कॉम्पैक्टनेस के लिए संशोधित है।

public static boolean isSymlink(File file) throws IOException { 
    if (file == null) 
    throw new NullPointerException("File must not be null"); 
    File canon; 
    if (file.getParent() == null) { 
    canon = file; 
    } else { 
    File canonDir = file.getParentFile().getCanonicalFile(); 
    canon = new File(canonDir, file.getName()); 
    } 
    return !canon.getCanonicalFile().equals(canon.getAbsoluteFile()); 
} 
+0

हम्म, ग्रे और एरिक्सन: वास्तव में यह ठीक काम करता प्रतीत होता है भले ही यह एक ही निर्देशिका में किसी फ़ाइल से लिंक हो। क्या आपके पास एक बिंदु परीक्षण है जो आपके बिंदु को चित्रित करता है? – Kutzi

+6

यह एनटीएफएस के साथ विंडोज पर काम नहीं करता है (जब symlink mklink के साथ बनाया जाता है)। – Ben

13

जावा 1.6 फ़ाइल सिस्टम के लिए निम्न स्तर तक पहुंच प्रदान नहीं करता है। ऐसा लगता है कि NIO 2, जिसे जावा 1.7 में शामिल किया जाना चाहिए, को प्रतीकात्मक लिंक के लिए समर्थन मिलेगा। A draft of the new API उपलब्ध है। प्रतीकात्मक लिंक are mentioned there, creating और following उन्हें संभव है। मुझे बिल्कुल यकीन नहीं है कि फ़ाइल को प्रतीकात्मक लिंक है या नहीं, यह जानने के लिए किस विधि का उपयोग किया जाना चाहिए। एनआईओ 2 पर चर्चा के लिए a mailing list है - शायद वे जान जाएंगे।

5

ऐसा लगता है कि getCanonicalPath() अन्य चीजें कर सकता है जो इसे पूर्ण पथ से अलग कर सकता है।

इस विधि पहले, यदि आवश्यक हो तो पूर्ण रूप को यह पथ रूपांतरण करता है तो के रूप में getAbsolutePath() विधि लागू करें, और उसके द्वारा एक प्रणाली पर निर्भर रास्ते में अपनी अनूठी फार्म के लिए यह मैप करता है। इसमें आम तौर पर अनावश्यक नामों को हटाने जैसे "।" और ".." पथनाम से, प्रतीकात्मक लिंक (यूनिक्स प्लेटफार्मों पर) को हल करना, और ड्राइव अक्षरों को एक मानक मामले (माइक्रोसॉफ्ट विंडोज प्लेटफॉर्म पर) में परिवर्तित करना।

लेकिन यह अपने उपयोग के मामलों के विशाल बहुमत के लिए काम कर सकते; आपकी माइलेज भिन्न हो सकती है।

1

क्षमा करें इस तरह के एक पुराने पोस्ट का जवाब देने के, लेकिन मैं विंडोज सिस्टम के लिए एक समाधान के लिए कुछ समय पहले देख रहा था, और पिछले जवाब में से कुछ मेरे लिए बाहर काम नहीं किया। यदि आप क्रॉस प्लेटफार्म संगतता से चिंतित नहीं हैं और केवल विंडोज के लिए समाधान की आवश्यकता है, तो निम्न तकनीक ने मेरे उद्देश्यों के लिए अच्छा काम किया है।

File f = new File("whatever file or folder"); 
if (f instanceof ShellFolder) { 
    ShellFolder sf = (ShellFolder)f; 
    if (sf.isLink()) { 
    // Your code when it's a link 
    } 
} 
+1

'शैलफोल्डर' 'rt.jar' – sjngm

+1

में 'sun.awt.shell.ShellFolder' प्रतीत होता है। मुझे नहीं लगता कि" नई फ़ाइल() "गतिशील रूप से शैलफ़ोल्डर का एक उदाहरण प्रस्तुत करेगी। यह FileChoser के परिणामस्वरूप काम करता है। – eckes

-2

मैंने सोचा कि मैं इस मुद्दे से निपटने में कुछ अच्छा भाग्य साझा करूंगा। मैं जेडीके 1.6.0_23 का उपयोग कर रहा हूं और इसलिए मुझे एनआईओ 2 से लाभ नहीं हो सकता है। मैं विंडोज 7/x64 पर केवल निर्माण और चल रहा हूं इसलिए अन्य वातावरण में माइलेज भिन्न हो सकता है। दुर्भाग्यवश, यहां अन्य समाधान एक जंक्शन को पार करने का प्रयास करते समय नलपॉन्टर अपवादों से बचने के लिए मेरे लिए काम नहीं करते थे (शायद क्योंकि जंक्शन! = Symlink ....)। जबकि मैं जेडीके संस्करण से बाध्य नहीं हूं, मैंने थोड़ी देर के लिए समस्या को रखने का फैसला किया।

मेरे पास यह कोड था जो एक प्रतीकात्मक लिंक पर या 'सिस्टम वॉल्यूम सूचना' निर्देशिका का सामना करते समय एक NullPointerException का कारण बनता है। (ध्यान दें, traverseItem.f() प्रकार java.io.File की एक वस्तु देता है)

if (traverseItem.f().isDirectory) { 
    for (File item : traverseItem.f().listFiles()) { 

इसलिए, यह माना जाता है कि एक निर्देशिका है, लेकिन listFiles() उस पर बुला एक एनपीई कारण बनता है। क्या करें? मैंने सूची() विधि पर जासूसी की और आश्चर्य किया कि क्या यह वही व्यवहार प्रदर्शित करेगा।मैंने जो खोजा वह निम्नलिखित था:

एक खाली फ़ोल्डर का वर्णन करने वाली फ़ाइल पर कॉलिंग सूची() लंबाई की एक स्ट्रिंग [] सरणी शून्य प्रदान करती है। हालांकि, एक फ़ाइल एक जंक्शन का वर्णन पर सूची() जो अन्यथा listFiles से दुर्घटना होगा() कॉल रिटर्न अशक्त

मैं listFiles()

String[] contents = traverseItem.f().list(); 
    if (contents != null) { //Non-traversible if null, possibly junction or ??? 

कॉल करने से पहले निम्न परीक्षण जोड़कर NullPointerExceptions से बचने के लिए कर रहा था यह जंक्शन, प्रतीकात्मक लिंक, हार्ड लिंक के सभी मामलों का पूरी तरह से परीक्षण करने के लिए बनी हुई है, और मैं इसका उल्लेख करता हूं, शॉर्टकट, लेकिन इससे कुछ मदद मिल सकती है।

+0

आपकी व्याख्या पूरी जगह पर है, ज्यादातर स्थानों में लगभग पूरी तरह से अप्रासंगिक लगता है, ज्यादातर दूसरों में गलत है, और आपके कोड स्निपेट बड़े पैमाने पर अपूर्ण हैं। अगर मैं कर सकता तो मैं यह 2 डाउनवॉट्स दूंगा। – searchengine27

11

इसके अलावा, के लिए file.isFile() और file.isDirectory() दोनों लौटने का संकल्प फ़ाइल और इसलिए दोनों लौटने false के आधार पर परिणाम देखना जब file एक सिमलिंक जहां लक्ष्य मौजूद नहीं है को दर्शाता है।

(मैं यह जानता हूँ अपने आप में एक उपयोगी जवाब नहीं है, लेकिन यह मेरे ऊपर फिसल गया एक दो बार तो सोचा था कि मैं साझा करना चाहिए)

+0

मैंने इस परिदृश्य को कभी नहीं माना होगा। अच्छा उल्लेख है। – kevinarpe

3

आप पहले से ही विशेष रूप से * nix के लिए कुछ कोडिंग कर रहे हैं, तो आप कर सकता है इस तरह जावा से एक शेल कमांड:

Process p = Runtime.getRuntime().exec(new String[]{"test", "-h", yourFileName}); 
p.waitFor(); 
if (p.exitValue() == 0) 
    System.out.println("This file is a symbolic link"); 
else 
    System.out.println("This file is not a symbolic link"); 

कि * nix के लिए बहुत विशिष्ट है, लेकिन यह कम से कम काम करता है।