2013-08-14 24 views
7

既存のファイルが特定のディレクトリまたはそのサブディレクトリにあるかどうかをチェックしたいと思います。ファイルが(サブ)ディレクトリにあるかどうかを確認してください

私は2つのFileオブジェクトを持っています。

File dir; 
File file; 

両方が存在することが保証されています。のは、私は、このチェックは、今私は、チェックをこのようにやっているため、真

を返すようにしたい

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

を想定してみましょう:

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

これは私の限られたテストで動作するようですが、私はわかりませんよこれにより、一部のオペレーティングシステムで問題が発生する可能性があります。私はgetCanonicalPath()が処理する必要がある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()。startsWith(parent.getAbsolutePath())'を簡単に使用できます。 – rocketboy

+0

実際には、getAbsolutePath()はそのような '/../'トークンをすべて計算し、ファイルシステムで実際の絶対パスを返します。 –

0

ファイルとファイル名で作品を計画している場合heavlyのapacheのfileutilsとfilenameutilsライブラリを確認してください。 (移植性がmamdatoryある場合とPORTALE)私は小さなユーティリティメソッドを作成します

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から始まるファイルツリーをたどることができます。 Java 7には、Files.walkFileTreeメソッドがあります。現在のノードが検索されたファイルであるかどうかを確認するには、自分自身の訪問者 を書き留める必要があります。その他のドキュメント:rocketboyからasnwerに加えて 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

getAbsolutePath()getCanonicalPath() instadを使用するので、\dir\dir2\..\file\dir\fileに変換されます。

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

または

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

いずれかをキャッチすることを忘れないでください。 Exceptiontry {...} catch {...}

注:File.separatorの代わりにFileSystem.getSeparator()を使用できます。これを行う '正しい'方法は、StringとしてチェックするディレクトリのgetCanonicalPath()を取得し、次にFile.separatorで終了するかどうかを確認し、そうでない場合は、Stringの末尾にFile.separatorを追加して回避します二重スラッシュ。Javaが末尾にスラッシュを含むディレクトリを返すことを決定した場合、またはディレクトリ文字列がJava.io.File以外の場所から来る場合、この方法で将来の奇妙な動作をスキップできます。

注2:File.separator問題を指摘するための@davidに注意してください。

+0

'/ a'と'/ab/test.txt'はどうですか? – david

+0

@david全く同じ結果を返します。バックスラッシュの代わりにスラッシュを要求すると、その動作はわかりませんが、OSネイティブを使用することをお勧めします。 Javaには、OSのネイティブディレクトリセパレータを返す関数がありますが、今は思い出せません。 –

+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によって溶液に似ていますが(つまり、この場合には大きな違いを作るべきではありませんが)再帰を使用していません。

関連する問題