Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are two File pointing to the same file?

I want to make sure that two java.io.File are not pointing to the same file, I have tried various methods, and finally found a way, but I want to make sure there is no loophole around it.

it's important because I am trying to write a program to delete duplicate files,and I don't want to end up deleting a unique file just because two java.io.File are pointing to the same 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();
}

on the side, is there a problem with my try-catch code? it gives me a warning when I run.

like image 845
hanbin615 Avatar asked Mar 17 '23 07:03

hanbin615


1 Answers

Yes, this should work. From the documentation:

A canonical pathname is both absolute and unique. The precise definition of canonical form is system-dependent. This method first converts this pathname to absolute form if necessary, as if by invoking the getAbsolutePath() method, and then maps it to its unique form in a system-dependent way. This typically involves removing redundant names such as "." and ".." from the pathname, resolving symbolic links (on UNIX platforms), and converting drive letters to a standard case (on Microsoft Windows platforms).

So this method should deal with:

  • redundant path parts such as /./
  • symlinks
  • relative paths

But I would strongly suggest you use Files.isSameFile:

If both Path objects are equal then this method returns true without checking if the file exists. If the two Path objects are associated with different providers then this method returns false. Otherwise, this method checks if both Path objects locate the same file, and depending on the implementation, may require to open or access both files.

Mainly because the java.io.File API has a large number of subtle bugs and API issues that cannot be worked around. But also because it has methods to do most common tasks built in.

like image 103
Boris the Spider Avatar answered Mar 23 '23 21:03

Boris the Spider