Java, Linux : how to detect whether two java. io.Files引用同一个物理文件

标签 java file unix equals

我正在寻找一种有效的方法来检测两个 java.io.File 是否引用同一个物理文件。根据文档,File.equals() 应该完成这项工作:

Tests this abstract pathname for equality with the given object. Returns true if and only if the argument is not null and is an abstract pathname that denotes the same file or directory as this abstract pathname.

但是,给定一个挂载在/media/truecrypt1 的 FAT32 分区(实际上是一个 TrueCrypt 容器):

new File("/media/truecrypt1/File").equals(new File("/media/truecrypt1/file")) == false

你说这符合规范吗?在这种情况下,如何解决该问题?

更新:感谢评论者,对于 Java 7,我找到了适合我的 java.io.Files.isSameFile()

最佳答案

@Joachim 评论中的答案通常是正确的。确定两个 File 对象是否引用同一个操作系统文件的方法是使用 getCanonicalFile() 或 getCanonicalPath()。 javadoc 是这样说的:

"A canonical pathname is both absolute and unique. [...] Every pathname that denotes an existing file or directory has a unique canonical form."

所以下面的应该工作:

File f1 = new File("/media/truecrypt1/File");  // different capitalization ...
File f2 = new File("/media/truecrypt1/file");  // ... but same OS file (on Windows)
if (f1.getCanonicalPath().equals(f2.getCanonicalPath())) {
    System.out.println("Files are equal ... no kittens need to die.");
}

但是,看起来您正在查看安装在 UNIX/Linux 上的 FAT32 文件系统。 AFAIK,Java 不知道这正在发生,只是对文件名应用通用的 UNIX/Linux 规则......在这种情况下会给出错误的答案。

如果这是真的发生的事情,我认为在纯 Java 6 中没有可靠的解决方案。但是,

  • 您可以做一些复杂的 JNI 工作;例如获取文件描述符编号,然后在 native 代码中使用 fstat(2)获取两个文件的设备和 inode 编号并进行比较的系统调用。

  • Java 7 java.nio.file.Path.equals(Object) 看起来如果您调用 resolve( ) 在路径上首先解析符号链接(symbolic link)。 (从 javadoc 中可以看出,Linux 上每个已安装的文件系统是否都对应于一个不同的 FileSystem 对象。)

  • Java 7 教程有 this section查看两个 Path 对象是否针对同一个文件...建议使用 java.nio.file.Files.isSameFile(Path, Path)


Would you say that this conforms to the specification?

不,是的。

  • 从某种意义上说,getCanonicalPath() 方法不会为每个现有的操作系​​统文件返回相同的值……这正是您阅读 javadoc 时所期望的。

  • 在技术意义上是的,Java 代码库(不是 javadoc)是最终规范......无论是在理论上还是在实践中。

关于Java, Linux : how to detect whether two java. io.Files引用同一个物理文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5883221/

相关文章:

linux - 删除空字符(Shell 脚本)

file - 监控数千个文件移动、删除和重命名的最佳 Cocoa 方式?

file - LaTeX hyperref 包 : Opening a target PDF at a specific page

java - 最佳编码方式

Bash - 读入文件并用一个逗号替换多个空格

java - 将抽象类存储在数组列表中

java - 为什么FullGC无法释放物理内存(RES)?

java - 空字符串验证

java - 尝试在 virgo tomcat 中配置自定义 session 管理器时获取 ClassNotFoundException

git - 删除我文件夹中的所有 .gitignore 文件