2013-08-14 9 views
7

है या नहीं, मैं यह जांचना चाहता हूं कि कोई मौजूदा फ़ाइल किसी विशिष्ट निर्देशिका में है या उसके उपनिर्देशिका में है या नहीं।जांचें कि फ़ाइल (उप) निर्देशिका

मेरे पास दो फ़ाइल ऑब्जेक्ट्स हैं।

File dir; 
File file; 

दोनों का अस्तित्व की गारंटी है।

String canonicalDir = dir.getCanonicalPath() + File.separator; 
boolean subdir = file.getCanonicalPath().startsWith(canonicalDir); 

यह मेरी सीमित परीक्षण के साथ काम करने लगता है, लेकिन मैं अनिश्चित हूं: मान लेते हैं

dir = /tmp/dir 
file = /tmp/dir/subdir1/subdir2/file.txt 

मैं इस चेक सच

वापस जाने के लिए अब मैं जांच इस तरह से कर रहा हूँ के लिए चाहते हैं क्या यह कुछ ऑपरेटिंग सिस्टम पर समस्याएं पैदा कर सकता है। मुझे यह भी पसंद नहीं है कि कैनोनिकलपाथ() एक IOException फेंक सकता है जिसे मुझे संभालना है।

क्या कोई बेहतर तरीका है? शायद कुछ पुस्तकालय में?

धन्यवाद

उत्तर

-1

पथ की तुलना करने के बारे में कैसे?

boolean areRelated = file.getAbsolutePath().contains(dir.getAbsolutePath()); 
    System.out.println(areRelated); 

या

boolean areRelated = child.getAbsolutePath().startsWith(parent.getAbsolutePath()) 
+2

यह उन पथों के लिए समस्याग्रस्त हो सकता है जिनमें "/tmp/something/../dir" जैसी सामग्री शामिल है जो मेरे आवेदन में संभव है। –

+0

आप आसानी से 'child.getAbsolutePath() शुरू कर सकते हैं। शुरू होता है (parent.getAbsolutePath()) 'अगर ऐसा है। – rocketboy

+0

वास्तव में getAbsolutePath() सभी ऐसे '/../' टोकन की गणना करेगा और फ़ाइल सिस्टम में वास्तविक पूर्ण पथ लौटाएगा। –

0

आप फ़ाइल और फ़ाइल नामों के साथ काम करता है की योजना है अपाचे fileutils और पुस्तकालयों filenameutils जाँच heavly। उपयोगी से भरे हुए हैं (और portale यदि पोर्टेबिलिटी mamdatory है) काम करता है

0
public class Test { 
public static void main(String[] args) { 
    File root = new File("c:\\test"); 
    String fileName = "a.txt"; 
    try { 
     boolean recursive = true; 

     Collection files = FileUtils.listFiles(root, null, recursive); 

     for (Iterator iterator = files.iterator(); iterator.hasNext();) { 
      File file = (File) iterator.next(); 
      if (file.getName().equals(fileName)) 
       System.out.println(file.getAbsolutePath()); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

}

10

मैं एक छोटे उपयोगिता विधि बनाना होगा:

public static boolean isInSubDirectory(File dir, File file) { 

    if (file == null) 
     return false; 

    if (file.equals(dir)) 
     return true; 

    return isInSubDirectory(dir, file.getParentFile()); 
} 
+2

मैं पहले जांच करता हूं कि फ़ाइल वास्तव में एक फ़ाइल है या नहीं। और हो सकता है कि [माता-पिता को ढूंढें] (http://stackoverflow.com/questions/11296949/created-file-has-no-parent)। यह एक अच्छा विचार की तरह लगता है, लेकिन यह एक बड़े समाधान का हिस्सा होना चाहिए। –

0

आप फ़ाइल ट्री पार कर सकते हैं अपने विशिष्ट DIR से शुरू । जावा 7 पर, Files.walkFileTree विधि है। वर्तमान नोड की खोज की गई फ़ाइल को जांचने के लिए आपको केवल अपने स्वयं के आगंतुक लिखना है। अधिक दस्तावेज़:

boolean areRelated = file.getCanonicalPath().contains(dir.getCanonicalPath() + File.separator); 
    System.out.println(areRelated); 

या

boolean areRelated = child.getCanonicalPath().startsWith(parent.getCanonicalPath() + File.separator); 

मत भूलना किसी भी पकड़ने के लिए: http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#walkFileTree%28java.nio.file.Path,%20java.util.Set,%20int,%20java.nio.file.FileVisitor%29

7

Rocketboy से asnwer के अलावा, getAbsolutePath() की getCanonicalPath() instad तो \dir\dir2\..\file\dir\file में बदल जाती है का उपयोग Exceptiontry {...} catch {...} के साथ।

नोट: आप File.separator के बजाय FileSystem.getSeparator() का उपयोग कर सकते हैं। ऐसा करने का 'सही' तरीका उस निर्देशिका के getCanonicalPath() को प्राप्त करने के लिए होगा, जिसे आप String के रूप में जांचने जा रहे हैं, फिर File.separator के साथ समाप्त होने पर जांचें और यदि नहीं तो के अंत में File.separator जोड़ें, इससे बचने के लिए डबल स्लेश।इस तरह आप भविष्य में अजीब व्यवहार छोड़ देते हैं यदि जावा अंत में स्लैश के साथ निर्देशिकाएं वापस करने का निर्णय लेता है या यदि आपकी निर्देशिका स्ट्रिंग Java.io.File से कहीं और से आती है।

नोट 2: File.separator समस्या को इंगित करने के लिए Thanx @david।

+0

'/ a' और'/ab/test.txt' के बारे में क्या? – david

+0

@ डेविड बिल्कुल वही वापस आ जाएगा। यदि आप बैकस्लाश के बजाय स्लेश के लिए पूछते हैं, तो मुझे व्यवहार नहीं पता है, लेकिन मेरी सिफारिश ओएस मूल का उपयोग करना है। जावा में ओएस मूल निर्देशिका विभाजक को वापस करने के लिए एक फ़ंक्शन है, लेकिन मुझे अभी यह याद नहीं है। –

+0

मेरा बिंदु स्लेश की दिशा के बारे में बिल्कुल नहीं था; मैं एक काउंटर उदाहरण दे रहा था जिसके परिणामस्वरूप आपके उत्तर में रणनीति का उपयोग करके गलत जवाब मिलेगा। – david

4

इस विधि बहुत ठोस दिखता है:

/** 
* Checks, whether the child directory is a subdirectory of the base 
* directory. 
* 
* @param base the base directory. 
* @param child the suspected child directory. 
* @return true, if the child is a subdirectory of the base directory. 
* @throws IOException if an IOError occured during the test. 
*/ 
public boolean isSubDirectory(File base, File child) 
    throws IOException { 
    base = base.getCanonicalFile(); 
    child = child.getCanonicalFile(); 

    File parentFile = child; 
    while (parentFile != null) { 
     if (base.equals(parentFile)) { 
      return true; 
     } 
     parentFile = parentFile.getParentFile(); 
    } 
    return false; 
} 

Source

यह dacwe द्वारा समाधान के समान है लेकिन प्रत्यावर्तन का उपयोग नहीं करता (कि हालांकि इस मामले में एक बड़ा अंतर नहीं होना चाहिए) ।

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