简体   繁体   English

如何比较 Java 中的 Path 等价性?

[英]How does one compare Path equivalence in Java?

Given two Path objects p1 and p2 (that do not necessarily point to a file that exists), how do I check the underlying paths are equivalent?给定两个 Path 对象 p1 和 p2(不一定指向存在的文件),如何检查底层路径是否等效? That is, Path objects arising from也就是说,Path 对象产生于

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

should (for instance) be regarded as equivalent / the same.应该(例如)被视为等效/相同。

My current approaches would be to我目前的方法是

  1. Use Files.isSameFile使用 Files.isSameFile
  2. First apply .normalize() on each Path object and then use .equals on one of the new Paths.首先在每个 Path 对象上应用 .normalize() ,然后在新路径之一上使用 .equals 。

Do these two approaches lead to the same result?这两种方法会导致相同的结果吗? I have tried to read the documentation, and my current guess is that the results should be the same.我试图阅读文档,我目前的猜测是结果应该是一样的。

Edit: Multiple people have suggested that the following article answers my question.编辑:多人建议以下文章回答我的问题。 I claim that this is incorrect, since it only explains why Files.isSameFile() is distinct from Path#equals().我声称这是不正确的,因为它只解释了为什么 Files.isSameFile() 与 Path#equals() 不同。 The question (nor its answers) do not consider whether .normalize() is of relevance.问题(或其答案)不考虑 .normalize() 是否相关。 Java NIO - How is Files.isSameFile different from Path.equals Java NIO - Files.isSameFile 与 Path.equals 有何不同

There is a difference between mentioned approaches in case of relative paths or reparse points:在相对路径或重解析点的情况下,上述方法之间存在差异:

  1. Files.isSameFile does a deep check, eg under Windows it opens both files and compares volume ids and file system indexes within that volume. Files.isSameFile进行深度检查,例如在 Windows 下,它会打开两个文件并比较该卷中的卷 ID 和文件系统索引。 So it can handle reparse points, relative paths, redundant path elements and even hardlinks (different file records pointing to same file contents).因此它可以处理重解析点、相对路径、冗余路径元素甚至硬链接(指向相同文件内容的不同文件记录)。 There are some pieces of decompiled byte code for Windows (I believe it will be similar for other systems):有一些用于 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 only normalizes path string w/o accessing file system, so it can't match "/path/file.ext" and "./file.ext" when current directory is "/path" or "C:\\dir\\file.ext", "C:file.ext" and "\\dir\\file.ext" under Windows if current directory is "C:\\dir", and it definitely doesn't follow links so may consider different routes to the same file as different files. Path.normalize只对不访问文件系统的路径字符串进行规范化,因此当当前目录为“/path”或“C:\\dir”时,它不能匹配“/path/file.ext”和“./file.ext” \\file.ext", "C:file.ext" 和 "\\dir\\file.ext" 在 Windows 下,如果当前目录是 "C:\\dir",并且它绝对不跟随链接,所以可以考虑不同的路由到同一个文件作为不同的文件。

So depending on your needs there may be more than one sufficient approach:因此,根据您的需求,可能有不止一种足够的方法:

  1. If you need the fastest way and know that there are no reparse points and both paths are absolute, it should be safe to use Path.normalize for both paths.如果您需要最快的方式并且知道没有重解析点并且两条路径都是绝对路径,那么对两条路径使用Path.normalize应该是安全的。 You should use File.getAbsolutePath before normalizing if paths may be relative because normalization doesn't handle it.如果路径可能是相对的,您应该在规范化之前使用File.getAbsolutePath ,因为规范化不处理它。
  2. If you have to be absolutely sure that both paths refer to the same file, use Files.isSameFile .如果您必须绝对确定两个路径都指向同一个文件,请使用Files.isSameFile
  3. You can also use Path.toRealPath method for resolving any reparse points in path so applying it on both paths should give almost same result as Files.isSameFile but in a different way (maybe slower or faster, also it will not match hardlinks while Files.isSameFile will).您还可以使用Path.toRealPath方法来解析路径中的任何重解析点,因此在两个路径上应用它应该给出与Files.isSameFile几乎相同的结果,但以不同的方式(可能更慢或更快,它也不会匹配硬链接,而 Files.isSameFile Files.isSameFile将)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM