Java 1.6 – 确定符号链接

在一个DirectoryWalker类中,我想知道一个File实例是否是一个到目录的符号链接(假设Walker在UNIX系统上行走)。 鉴于,我已经知道这个实例是一个目录,下面是一个确定符号链接的可靠条件吗?

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

Apache Commons中使用的技术使用父目录的规范path,而不是文件本身。 我不认为你可以保证一个错配是由于一个象征性的联系,但这是一个很好的迹象表明,文件需要特殊的处理。

这是Apache代码 (取决于他们的许可证 ),修改为紧凑。

 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()); } 

Java 1.6不提供对文件系统的低级访问。 看起来应该包含在Java 1.7中的NIO 2将支持符号链接。 新API的草稿可用。 符号链接在那里提到 , 创build和跟随它们是可能的。 我不确定应该使用哪种方法来确定文件是否是符号链接。 有一个讨论NIO 2 的邮件列表 – 也许他们会知道。

另外,注意file.isFile()file.isDirectory()都返回基于parsing文件的结果,因此当file引用目标file不存在的符号链接时,它们都返回false

(我知道这不是一个有用的答案本身,但它绊了我几次,所以认为我应该分享)

它看起来像getCanonicalPath()可以做其他事情,可能会使其不同于绝对path。

如果需要,此方法首先将此path名转换为绝对forms,就像调用getAbsolutePath()方法一样,然后以依赖于系统的方式将其映射到其唯一forms。 这通常涉及删除多余的名称,如“。” 和“..”,parsing符号链接(在UNIX平台上),并将驱动器号转换为标准大小写(在Microsoft Windows平台上)。

但是它可能适用于绝大多数的用例。 你的旅费可能会改变。

如果您已经为* nix专门编写了一些东西,那么您可以像这样从Java执行一个shell命令:

 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,但它至less工作。

对不起,回复这样一个旧的post,但我一直在寻找Windows系统的解决scheme,一些以前的答案没有为我工作。 如果你不关心跨平台的兼容性,只需要Windows的解决scheme,下面的技术对我的目的很好。

 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 } } 

我想我会分享一些我在处理这个问题上的好运。 我正在使用JDK 1.6.0_23,所以我不能从NIO2中受益。 我正在Windows 7 / x64上构build和运行,所以在其他环境中的里程可能会有所不同。 不幸的是,这里的其他解决scheme并不适用于避免尝试遍历结点时引起的NullPointerException(可能是因为结点!=符号链接….)。 虽然我不受JDK版本的限制,但我决定继续处理这个问题。

我有这样的代码,如果在符号链接上使用或在遇到“系统卷信息”目录时会导致NullPointerException。 (注意,traverseItem.f()返回一个java.io.Filetypes的对象)

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

所以,它应该是一个目录,但调用listFiles()会导致一个NPE。 该怎么办? 我窥探了list()方法,并想知道它是否会performance出相同的行为。 我发现了以下内容:

在描述空文件夹的File上调用list()会返回一个长度为零的String []数组。 然而,调用list()中描述一个会从listFiles()返回null的文件的list()将返回null

我可以通过在调用listFiles()之前添加以下testing来避免NullPointerExceptions

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

它仍然要详尽地testing所有的交叉点,符号链接,硬链接,并敢于提及它,捷径,但这可能会有所帮助。