两个文件是否指向同一个文件?

use*_*830 2 java file-comparison

我想确保两个java.io.File没有指向同一个文件,我尝试了各种方法,最后找到了一种方法,但我想确保它周围没有漏洞.

这很重要,因为我正在尝试编写一个删除重复文件的程序,我不想因为两个java.io.File指向同一个文件而最终删除一个唯一的文件.

File f1 = new File("file.txt");
File f2 = new File("./file.txt");
//these methods can't tell it's the same file
System.out.println(f1.compareTo(f2)); // 56 which mean not equal
System.out.println(f1.equals(f2)); // false
System.out.println(f1 == f2); // false
System.out.println(f1.getAbsolutePath().compareTo(f2.getAbsolutePath())); // 56

// this method can tell it's the same file... hopefully.
try{
    System.out.println(f1.getCanonicalPath().compareTo(f2.getCanonicalPath())); // 0
}catch (Exception e){
    e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

另一方面,我的try-catch代码有问题吗?我跑的时候会给我一个警告.

Bor*_*der 5

是的,这应该有效.从文档:

规范路径名既是绝对的,也是唯一的.规范形式的精确定义取决于系统.如果需要,此方法首先将此路径名转换为绝对形式,就像调用getAbsolutePath()方法一样,然后以依赖于系统的方式将其映射到其唯一形式.这通常涉及删除冗余名称,例如"." 和路径名中的"..",解析符号链接(在UNIX平台上),并将驱动器号转换为标准情况(在Microsoft Windows平台上).

所以这个方法应该处理:

  • 冗余路径部分如 /./
  • 符号链接
  • 相对路径

但我强烈建议你使用Files.isSameFile:

如果两个Path对象相等,则此方法返回true,而不检查文件是否存在.如果两个Path对象与不同的提供者关联,则此方法返回false.否则,此方法检查两个Path对象是否都找到相同的文件,并且根据实现,可能需要打开或访问这两个文件.

主要是因为java.io.FileAPI有大量微妙的错误和API问题,无法解决.但也因为它有方法来完成最常见的任务.