给定两个 Path 对象 p1 和 p2(不一定指向存在的文件(,如何检查底层路径是否等效?也就是说,Path 对象产生于
/path/to/something
/path/to/../fdsfaf/something
应(例如(被视为等同/相同。
我目前的做法是
- 使用 Files.isSameFile
- 首先在每个 Path 对象上应用 .normalize((,然后在其中一个新 Path 上使用 .equals。
这两种方法是否会导致相同的结果?我尝试阅读文档,我目前的猜测是结果应该相同。
编辑: 很多人建议下面的文章回答我的问题。我声称这是不正确的,因为它只解释了为什么 Files.isSameFile(( 与 Path#equals(( 不同。这个问题(及其答案(不考虑 .normalize(( 是否相关。 Java NIO - Files.isSameFile 与 Path.equals 有何不同
在相对路径或重分析点的情况下,上述方法之间存在差异:
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;
}
...
}
- 当前目录为"C:\dir",则在Windows下它不能匹配"/path/file.ext"和"./file.ext",并且它绝对不遵循链接,因此可能会将指向同一文件的不同路由视为不同的文件。
Path.normalize
仅规范化不访问文件系统的路径字符串,因此当当前目录为"/path"或"C:\dir\file.ext","C:file.ext"和"\dir\file.ext"时,如果因此,根据您的需求,可能有多种足够的方法:
- 如果您需要最快的方法,并且知道没有重新分析点并且两条路径都是绝对的,那么对两条路径使用
Path.normalize
应该是安全的。如果路径可能是相对的,则应在规范化之前使用File.getAbsolutePath
,因为规范化不会处理它。 - 如果必须绝对确定两个路径引用同一个文件,请使用
Files.isSameFile
。 - 您还可以使用
Path.toRealPath
方法来解析路径中的任何重新分析点,因此在两条路径上应用它应该给出与Files.isSameFile
几乎相同的结果,但方式不同(可能更慢或更快,它也不会匹配硬链接,而Files.isSameFile
会(。