java - 如何比较 Java 中的路径等效性?
问题描述
给定两个 Path 对象 p1 和 p2(不一定指向存在的文件),我如何检查底层路径是否等效?也就是说,Path 对象产生于
/path/to/something
/path/to/../fdsfaf/something
应该(例如)被视为等效/相同。
我目前的方法是
- 使用 Files.isSameFile
- 首先在每个 Path 对象上应用 .normalize(),然后在其中一个新路径上使用 .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;
}
...
}
Path.normalize
仅规范化不访问文件系统的路径字符串,因此当当前目录为“/path”或“C:\dir\file”时,它不能匹配“/path/file.ext”和“./file.ext”。如果当前目录是“C:\dir”,则 Windows 下的 ext”、“C:file.ext”和“\dir\file.ext”,并且它肯定不跟随链接,因此可能会考虑到同一个文件的不同路径不同的文件。
因此,根据您的需要,可能有不止一种足够的方法:
- 如果您需要最快的方法并且知道没有重解析点并且两条路径都是绝对的,那么两条路径都应该是安全的
Path.normalize
。如果路径可能是相对的,则应File.getAbsolutePath
在规范化之前使用,因为规范化无法处理它。 - 如果您必须绝对确定两个路径都引用同一个文件,请使用
Files.isSameFile
. - 您还可以使用
Path.toRealPath
方法来解决路径中的任何重解析点,因此在两条路径上应用它应该给出几乎相同的结果,Files.isSameFile
但以不同的方式(可能更慢或更快,也不会匹配硬链接Files.isSameFile
)。
推荐阅读
- docker - 当我通过节点端口 i 访问应用程序时,未获取更改
- html - 如何使 HTML 和 CSS 下拉菜单正常工作?
- email - 使用 Smarty 检查字符串是否包含子字符串
- python - 读取一行或 idk 时的 EOF
- wpf - 异常未在 try-catch 中捕获
- angular - 缺少 int 类型的方法参数的 URI 模板变量“pagesize”
- python - 有没有办法在 sqlite 的 where 子句中包含多个变量?
- python - 如何从列表中过滤空字符串和回车?
- reactjs - 在 Firebase Analytics for Web 中跟踪默认事件
- python - 如何将 PATH 参数从脚本传递到批处理文件?