I was wondering how I could check if fileSystems of two different paths are equal. It seems wrong to write something like
path1.fileSystem == path2.fileSystem
because there could be a case when file systems are the same by meaning (they are fully identical), but in fact are different instances and because of that path1.fileSystem == path2.fileSystem
may return false
when it must actually return true
. Then how should I compare file systems of two different paths? Or is ==
actually okay and works correctly in this situation?
I actually tried asking ChatGPT, but it gave me a weird solution that doesn't seem to work
boolean sameFileSystem = FileSystems.getDefault().provider().getScheme().equals(path1.getFileSystem().provider().getScheme())
&& FileSystems.getDefault().provider().getScheme().equals(path2.getFileSystem().provider().getScheme());
Update: I need to check this in order to resolve one path against another (if the file systems are not the same I will just do something else, this part is irrelevant? i Just need to check if they are the same)
If you want to know whether you can safely invoke .resolve(Path)
for two existing Path
instances, you must check whether the two path belong to the same provider, rather than filesystem.
Providers can be compared using the ==
operator; they are supposed to be singletons.
For comparison, this is how Files.copy(…)
checks whether the two paths belong to the same filesystem provider:
public static Path copy(Path source, Path target, CopyOption... options) throws IOException { FileSystemProvider provider = provider(source); if (provider(target) == provider) { // same provider provider.copy(source, target, options); } else { // different providers CopyMoveHelper.copyToForeignTarget(source, target, options); } return target; }
…
private static FileSystemProvider provider(Path path) { return path.getFileSystem().provider(); }
In most cases, a fallback using .resolve(String)
works when you need to resolve with paths of different filesystem providers:
static Path resolveWithForeignSupport(Path base, Path other) {
FileSystem fs1 = base.getFileSystem(), fs2 = other.getFileSystem();
if(fs1.provider() == fs2.provider()) {
return base.resolve(other);
}
if(other.getNameCount() <= 1 || fs1.getSeparator().equals(fs2.getSeparator())){
return base.resolve(other.toString());
}
Path resolved = base, othersRoot = other.getRoot();
if(othersRoot != null) {
resolved = resolved.resolve(othersRoot.toString());
}
for(Path component: other) {
resolved = resolved.resolve(component.toString());
}
return resolved;
}