Given two Path objects p1 and p2 (that do not necessarily point to a file that exists), how do I check the underlying paths are equivalent? That is, Path objects arising from
/path/to/something
/path/to/../fdsfaf/something
should (for instance) be regarded as equivalent / the same.
My current approaches would be to
Do these two approaches lead to the same result? I have tried to read the documentation, and my current guess is that the results should be the same.
Edit: Multiple people have suggested that the following article answers my question. I claim that this is incorrect, since it only explains why Files.isSameFile() is distinct from Path#equals(). The question (nor its answers) do not consider whether .normalize() is of relevance. Java NIO - How is Files.isSameFile different from Path.equals
There is a difference between mentioned approaches in case of relative paths or reparse points:
Files.isSameFile does a deep check, e.g. under Windows it opens both files and compares volume ids and file system indexes within that volume. So it can handle reparse points, relative paths, redundant path elements and even hardlinks (different file records pointing to same file contents). There are some pieces of decompiled byte code for Windows (I believe it will be similar for other systems):public class WindowsFileSystemProvider extends AbstractFileSystemProvider {
...
public boolean isSameFile(Path var1, Path var2) throws IOException {
...
var11 = WindowsFileAttributes.isSameFile(var7, var10);
...
return var11;
...
}
...
}
class WindowsFileAttributes implements DosFileAttributes {
...
static boolean isSameFile(WindowsFileAttributes var0, WindowsFileAttributes var1) {
return var0.volSerialNumber == var1.volSerialNumber && var0.fileIndexHigh == var1.fileIndexHigh && var0.fileIndexLow == var1.fileIndexLow;
}
...
}
Path.normalize only normalizes path string w/o accessing file system, so it can't match "/path/file.ext" and "./file.ext" when current directory is "/path" or "C:\dir\file.ext", "C:file.ext" and "\dir\file.ext" under Windows if current directory is "C:\dir", and it definitely doesn't follow links so may consider different routes to the same file as different files.So depending on your needs there may be more than one sufficient approach:
Path.normalize for both paths. You should use File.getAbsolutePath before normalizing if paths may be relative because normalization doesn't handle it.Files.isSameFile.Path.toRealPath method for resolving any reparse points in path so applying it on both paths should give almost same result as Files.isSameFile but in a different way (maybe slower or faster, also it will not match hardlinks while Files.isSameFile will).If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With