Java NIO - How is Files.isSameFile different from Path.equals
Asked Answered
N

5

13

I could not understand how java.nio.file.Files.isSameFile method is different from java.nio.file.Path.equals method.

Could anybody please tell how they are different?

Neale answered 31/3, 2015 at 12:8 Comment(4)
java.nio.file.Path.isSameFile doesn't exist. Do you mean java.nio.file.Files.isSameFile?Mckenney
Yes. You are right. Ohh that makes this question invalid. Requested to delete this question.Neale
You can just edit it and fix the mistakeGramme
The reason I asked the question is because, I felt isSameFile & equals are implementing similar behavior in same class. Now that I know they are from different classes, my original doubt doesn't exist.Neale
G
27

They are very different.

For instance:

final Path p1 = Paths.get("/usr/src");
final Path p2 = Paths.get("/usr/../usr/src");

p1.equals(p2); // FALSE
Files.isSameFile(p1, p2); // true

final Path p1 = fs1.getPath("/usr/src");
final Path p2 = fs2.getPath("/usr/src");

p1.equals(p2); // FALSE

A Path is equal to another Path if and only if:

  • they have the same FileSystem;
  • they have the same root element;
  • they have the same name elements.

This is very different from Files.isSameFile() which accesses the filesystem and tries and see if two Paths point to the same filesystem resource.

Gramme answered 31/3, 2015 at 12:12 Comment(3)
ok. So equals is just an equal check on its string representation, correct?Neale
No. Read the answer again.Gramme
Perhaps the OP is unaware that a file can have more than one path that identifies it? The differences range from the trivial (upper/lower case, elements like '..', etc) to the situation that a file in most file systems can have multiple links to it.Mannie
C
3
  • if equal() == true then isSameFile() == true
  • if isSameFile() == true, equal() is not always true

The isSameFile() method first checks if the Path objects are equal in terms of equal(), and if so, it automatically returns true without checking to see if either file exists.

If the Path object equals() comparison returns false, then it locates each file to which the path refers in the file system and determines if they are the same, throwing a checked IOException if either file does not exist.

Coryden answered 22/3, 2017 at 22:11 Comment(1)
just to add, according to the javadoc, File.isSameFile() can throw an exception, Path.equals() does not. docs.oracle.com/javase/7/docs/api/java/nio/file/… and docs.oracle.com/javase/7/docs/api/java/nio/file/… However it also mentions that in some circumstances Path.equals() will call Files.isSameFile()Agranulocytosis
M
1

isSameFile is from java.nio.file.Files and Path.equals is from java.nio.file.Path

isSameFile --> Tests if two paths locate the same file. ie) checks two Path objects are for the same file equals --> Tests this path for equality with the given object.

Munitions answered 31/3, 2015 at 12:15 Comment(1)
You are right, that makes my question an invalid one. I have requested to delete the question. Thanks for answering though.Neale
B
0

java.nio.file.Files.isSameFile() checks if two filepaths refers to the same file = i.e. both are hardlinks (this is portable for all OS and filesystems (yeah)). This method traverse symbolic links too then you can compare two symbolic links to filenames points to the same inode on unix filesystem/Windows NTFS.

You can locate (not editable) file duplicates (this same size and content), determines if are soft/hard links then if not - you can save pathname and delete first then create link to second. You can save 50% disk space.

Boycott answered 30/1, 2018 at 1:21 Comment(0)
A
0

From my point of view java APIs are missing something here... There should be a method to know if two paths are pointing to the same folder/file into the file system. And this should be performed without any access to the file system (put the case one of the paths is not existing, using java.nio.file.Files.isSameFile() you will receive a java.nio.file.NoSuchFileException). On the other hand

Paths.get("/usr/src").equals(Paths.get("/usr/../usr/src"))

will return a false result...

An easy solution for that situation might be the following:

final Path p1 = Paths.get("/usr/src");
final Path p2 = Paths.get("/usr/../usr/src");
final boolean areEqual = p1.normalize().toAbsolutePath().toString().equalsIgnoreCase(p2.normalize().toAbsolutePath().toString());

What do you think about it?

Anechoic answered 18/4, 2023 at 21:17 Comment(2)
There should be a method to know if two paths are pointing to the same folder/file into the file system. A system can't even do something like toAbsolutePath() without accessing the filesystem. It can't check if the file exists or not without accessing the filesystem. It can't follow soft links without accessing the file system. It can't check if two wildly different paths are actually hard links to the same file without accessing the file system.Atmosphere
Thanks Andrew for your comment, you are right, I didn't know that also toAbsolutePath() accesses to the file system. Anyway it seams not throwing any exception if a path doesn't exist. I mean, I was speacking of Path as a 'logical' form of system path. From that point of view, even the equals() method whould have been designed to work in a 'logical' manner and not physical. Of course, links, cannot be investigated without accessing the file system. Thanks again!Anechoic

© 2022 - 2025 — McMap. All rights reserved.