mst*_*rap 9 java unix file equals
我正在寻找一种有效的方法来检测两个是否java.io.File
引用相同的物理文件.根据文档,File.equals()
应该做的工作:
测试此抽象路径名与给定对象的相等性.当且仅当参数不为null并且是表示与此抽象路径名相同的文件或目录的抽象路径名时,返回true.
但是,给定一个安装在/ media/truecrypt1的FAT32分区(实际上是TrueCrypt容器):
new File("/media/truecrypt1/File").equals(new File("/media/truecrypt1/file")) == false
Run Code Online (Sandbox Code Playgroud)
你会说这符合规范吗?在这种情况下,如何解决这个问题?
更新:感谢评论者,对于Java 7,我发现java.io.Files.isSameFile()
哪些对我有用.
Ste*_*n C 14
@Joachim的评论中的答案通常是正确的.确定两个File
对象是否引用相同OS文件的方法是使用getCanonicalFile()或getCanonicalPath().javadoc说:
"规范路径名是绝对的和唯一的.[...]每个表示现有文件或目录的路径名都具有唯一的规范形式."
所以以下应该有效:
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.");
}
Run Code Online (Sandbox Code Playgroud)
但是,您似乎正在查看安装在UNIX/Linux上的FAT32文件系统.AFAIK,Java并不知道这种情况正在发生,并且只是对文件名应用通用的UNIX/Linux规则......在这种情况下给出了错误的答案.
如果这是真正发生的事情,我认为纯Java 6中没有可靠的解决方案.但是,
你可以做一些毛茸茸的JNI东西; 例如,获取文件描述符编号,然后在本机代码中,使用fstat(2)
系统调用来获取两个文件的设备和inode编号并进行比较.
如果首先调用路径来解析符号链接,Java 7 java.nio.file.Path.equals(Object)
看起来可能会给出正确的答案resolve()
.(从javadoc有点不清楚Linux上每个挂载的文件系统是否都对应一个不同的FileSystem
对象.)
在Java 7的教程有本节上看到如果两个Path
对象是同一个文件......这建议使用java.nio.file.Files.isSameFile(Path, Path)
你会说这符合规范吗?
不,是的.
从某种意义上说,该getCanonicalPath()
方法没有为每个现有的OS文件返回相同的值...这是您对读取javadoc的期望.
是技术意义上的,Java代码库(不是javadoc)是最终的规范......无论是在理论上还是在实践中.