2009-05-01 14 views
39

DirectoryWalkerクラスでは、Fileインスタンスが実際にディレクトリへのシンボリックリンクであるかどうかを調べたいと思います(ウォーカーはUNIXシステムを使用していると仮定します)。私はすでにインスタンスがディレクトリであることを知っていますが、シンボリックリンクを決定するには信頼できる条件が必要ですか?Java 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

Java 1.7:[java.nio.Files.isSymbolicLink(Path)](http:// docs 。//javas/7/docs/api/java/nio/file/Files.html#isSymbolicLink%28java.nio.file.Path%29) - もっと自分自身のために注意してください。 –

答えて

45

Apache Commonsで使用される手法では、ファイル自体ではなく、親ディレクトリへの標準パスが使用されます。私は不一致がシンボリックリンクによるものであることを保証できるとは思いませんが、ファイルが特別な扱いを必要としていることを示す良い指標です。

Apache codetheir 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

Hmm、Grayとerickson:実際には、同じディレクトリのファイルにリンクしても正常に動作するようです。あなたのポイントを示すユニットテストがありますか? – Kutzi

+6

これはNTFSのWindowsでは動作しません(symlinkがmklinkで作成された場合)。 – Ben

13

Java 1.6では、ファイルシステムに対する低レベルのアクセスが提供されていません。 Java 1.7に含まれるべきであるNIO 2のように見えますが、シンボリックリンクをサポートします。 A draft of the new APIが利用可能です。シンボリックリンクare mentioned there,creatingおよびfollowingが可能です。私は、ファイルがシンボリックリンクであるかどうかを調べるためにどのメソッドを使うべきか正確には分かりません。 NIO 2について議論するためのa mailing listがあります。多分彼らには分かるでしょう。

5

getCanonicalPath()は、絶対パスと異なる可能性があるその他のことを行う可能性があります。

このメソッドは、getAbsolutePath()メソッドを呼び出す場合と同じように、このパス名を必要に応じて絶対形式に変換し、システム固有の方法でその固有の形式にマップします。これには通常、 "。" (UNIXプラットフォームでは)シンボリックリンクを解決し、ドライブ文字を標準のケースに変換します(Microsoft Windowsプラットフォームでは)。

しかし、大部分の使用例ではうまくいく可能性があります。あなたのマイレージは異なる場合があります。

1

、このような古い投稿に返信申し訳ありませんが、私はいくつかの時間バックWindowsシステムのためのソリューションを探していた、と以前の回答の一部が私のために動作しませんでした。クロスプラットフォームとの互換性に関心がなく、Windows用のソリューションだけが必要な場合は、以下のテクニックが私の目的のためにうまくいきました。

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

'ShellFolder'は' rt.jar'の 'sun.awt.shell.ShellFolder'と思われます – sjngm

+1

"新しいFile() "はShellFolderのインスタンスを動的に生成しません。 FileChoserの結果として機能します。 – eckes

-2

私はこの問題に対処するために私が持っていたいくつかの幸運を共有すると思いました。私はJDK 1.6.0_23を使用しているので、NIO2を利用することはできません。私はWindows 7/x64上でビルドして稼働していますので、他の環境ではマイレージが異なる場合があります。残念ながら、ここで他の解決策は、(おそらくジャンクション!=シンボリックリンク....のために)ジャンクションをトラバースしようとしたときにNullPointerExceptionsが発生するのを避けるために私にとってはうまくいきませんでした。私はJDKのバージョンに制約されていませんが、私はもう少し長く問題に取り掛かることにしました。

シンボリックリンクで使用された場合、または「システムボリューム情報」ディレクトリに遭遇した場合、NullPointerExceptionを引き起こすこのコードがありました。

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

ので、それはおそらくディレクトリですが、それにLISTFILES()を呼び出すことはNPEが発生する(注、traverseItem.f()タイプのjava.io.Fileのオブジェクトを返します)。何をすべきか?私はlist()メソッドを信じて、同じ振る舞いをするかどうか疑問に思いました。私が発見したのは以下の通りです:

空のフォルダを記述するファイルの呼び出しリスト()は、長さゼロのString []配列を返します。しかし、そうでない場合(LISTFILESからクラッシュ接合を記述したファイルのリストを())を呼び出すと、nullを返します

私はLISTFILES()

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

を呼び出す前に、次のテストを追加することでNullPointerExceptionsがを避けることができましたそれは徹底的に接続、シンボリックリンク、ハードリンクのすべてのケースをテストするために残って、私はそれを、ショートカットを言いたいと敢えて、これはいくつかの助けになるかもしれません。

+0

あなたの説明はいたる所にあり、ほとんどの場所でほとんど完全に無関係で、ほとんどが不正確で、コードスニペットが大量に不完全です。もし私ができるなら、私はこの2 downvotesを与えるだろう。 – searchengine27

11

また、解決ファイルに基づいfile.isFile()file.isDirectory()の両方返す結果を見て、従ってfile、ターゲットが存在しないシンボリックリンクを指す場合falseを返す両方。

(私は、これは、それ自体で有用な答えではありません知っているが、それは私が共有しなければならないと思った数回私をトリップ)

+0

私はこのシナリオを決して考えなかったでしょう。いい言及。 – kevinarpe

3

あなたはすでに、あなたが行うことができ、特に* nixのために何かをコーディングしている場合このようなJavaからのシェルコマンド:

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に特有ですが、少なくとも動作します。

関連する問題