【问题标题】:How does one compare Path equivalence in Java?如何比较 Java 中的路径等效性?
【发布时间】:2020-01-18 18:11:57
【问题描述】:

给定两个 Path 对象 p1 和 p2(不一定指向存在的文件),我如何检查底层路径是否相等?即,Path 对象产生于

/path/to/something
/path/to/../fdsfaf/something

应该(例如)被视为等效/相同。

我目前的方法是

  1. 使用 Files.isSameFile
  2. 首先对每个 Path 对象应用 .normalize(),然后在其中一个新 Path 上使用 .equals。

这两种方法会导致相同的结果吗?我已经尝试阅读文档,我目前的猜测是结果应该是相同的。

编辑: 多人建议以下文章回答我的问题。我声称这是不正确的,因为它只解释了为什么 Files.isSameFile() 与 Path#equals() 不同。问题(及其答案)不考虑 .normalize() 是否相关。 Java NIO - How is Files.isSameFile different from Path.equals

【问题讨论】:

  • 这两种方法会导致相同的结果吗?您是否测试过?无需猜测。
  • 我在问我是否可以相信(至少根据定义)结果将是相同的。我的问题是(也)我对 Javadoc 的理解是否正确。
  • 是的,我已经读过了。但它没有回答我的问题。
  • 我只是写了它没有回答我的问题。 :-) 这个问题(包括它的答案)与 .normalize() 的使用无关

标签: java file path compare


【解决方案1】:

在相对路径或重解析点的情况下,上述方法之间存在差异:

  1. Files.isSameFile 进行深度检查,例如在 Windows 下,它会打开这两个文件并比较该卷中的卷 ID 和文件系统索引。因此它可以处理重解析点、相对路径、冗余路径元素甚至硬链接(指向相同文件内容的不同文件记录)。 Windows有一些反编译的字节码(我相信其他系统也会类似):
public class WindowsFileSystemProvider extends AbstractFileSystemProvider {
    ...

    public boolean isSameFile(Path var1, Path var2) throws IOException {
        ...
        var11 = WindowsFileAttributes.isSameFile(var7, var10);
        ...
        return var11;
        ...
    }

    ...
}

class WindowsFileAttributes implements DosFileAttributes {
    ...

    static boolean isSameFile(WindowsFileAttributes var0, WindowsFileAttributes var1) {
        return var0.volSerialNumber == var1.volSerialNumber && var0.fileIndexHigh == var1.fileIndexHigh && var0.fileIndexLow == var1.fileIndexLow;
    }

    ...
}
  1. Path.normalize 只对不访问文件系统的路径字符串进行规范化,因此当当前目录为“/path”或“C:\dir”时,它不能匹配“/path/file.ext”和“./file.ext” \file.ext", "C:file.ext" 和 "\dir\file.ext" 如果当前目录是 "C:\dir",则在 Windows 下,它肯定不跟随链接,所以可以考虑不同的路径到相同的文件和不同的文件。

因此,根据您的需要,可能有不止一种足够的方法:

  1. 如果您需要最快的方法并且知道没有重解析点并且两条路径都是绝对的,那么对两条路径都使用Path.normalize 应该是安全的。如果路径可能是相对的,您应该在规范化之前使用File.getAbsolutePath,因为规范化无法处理它。
  2. 如果您必须绝对确定两个路径都引用同一个文件,请使用Files.isSameFile
  3. 您还可以使用Path.toRealPath 方法来解析路径中的任何重解析点,因此在两条路径上应用它应该得到与Files.isSameFile 几乎相同的结果,但方式不同(可能更慢或更快,也不会匹配硬链接而Files.isSameFile 将)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-04
    • 2013-05-06
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多