代码之家  ›  专栏  ›  技术社区  ›  mats

Java 1.6 -确定符号链接

  •  40
  • mats  · 技术社区  · 17 年前

    在DirectoryWalker类中,我想知道文件实例是否实际上是指向目录的符号链接(假设Walker在Unix系统上行走)。给定,我已经知道实例是一个目录,下面的条件是否是确定符号链接的可靠条件?

    File file;
    // ...      
    if (file.getAbsolutePath().equals(file.getCanonicalPath())) {
        // real directory ---> do normal stuff      
    }
    else {
        // possible symbolic link ---> do link stuff
    }
    
    7 回复  |  直到 9 年前
        1
  •  45
  •   erickson    15 年前

    ApacheCommons中使用的技术使用父目录的规范路径,而不是文件本身。我认为您不能保证不匹配是由符号链接引起的,但这很好地表明文件需要特殊处理。

    这是 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());
    }
    
        2
  •  13
  •   Esko Luontola    17 年前

    Java 1.6不提供对文件系统的这种低级别访问。看起来像 NIO 2 应该包含在Java 1.7中,它将支持符号链接。 A draft of the new API 是可用的。符号链接 are mentioned there , creating following 它们是可能的。我不确定应该使用哪种方法来确定文件是否是符号链接。有 a mailing list 讨论NIO 2-也许他们会知道。

        3
  •  11
  •   Rob Oxspring    14 年前

    另外,注意 file.isFile() file.isDirectory() 两者都基于解析的文件返回结果,因此都返回 false 什么时候? file 指目标不存在的符号链接。

    (我知道这本身并不是一个有用的答案,但它让我有几次被绊倒了,所以我想我应该分享一下)

        4
  •  5
  •   Michael Myers KitsuneYMG    17 年前

    看起来像 getCanonicalPath() 可以做其他可能使它不同于绝对路径的事情。

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

    但它可能适用于绝大多数用例;您的里程数可能会有所不同。

        5
  •  3
  •   Beaker    14 年前

    如果你已经为*nix专门编码了一些东西,那么你可以像这样做一个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");
    

    这对尼克斯来说是非常具体的,但它至少起作用。

        6
  •  1
  •   Joachim Sauer    15 年前

    很抱歉回复了这么一篇旧的文章,但我想找一个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
      }
    }
    
        7
  •  -2
  •   user602347    15 年前

    我想在处理这个问题时我会分享一些好运气。我使用的是JDK 1.6.0,因此我无法从NIO2中获益。我只是在Windows7/x64上构建和运行,这样其他环境中的里程数可能会有所不同。不幸的是,这里的其他解决方案在避免尝试遍历连接时导致的NullPointerExceptions(可能是因为连接)方面不起作用。=符号链接….)。虽然我不受JDK版本的约束,但我决定将这个问题保持更长的时间。

    我有这个代码,如果在符号链接上使用或者遇到“系统卷信息”目录时,会导致nullpointerException。(注:TraveSimult.f-()返回一个Java.IO文件的对象)

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

    所以,它应该是一个目录,但是对它调用listfiles()会导致NPE。怎么办?我发现了list()方法,想知道它是否会表现出相同的行为。我发现的是:

    对描述空文件夹的文件调用list()将返回长度为零的字符串[]数组。但是,对描述连接的文件调用list(),否则将从listfiles()崩溃,返回空值。

    通过在调用listfiles()之前添加以下测试,我可以避免nullpointerExceptions。

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

    它仍然要详尽地测试所有的连接、符号链接、硬链接,我敢说它是快捷方式,但这可能会有所帮助。

    推荐文章