14

[note: self answered question]

I have opened a FileSystem to a zip file using java.nio. I have gotten a Path from that filesystem:

final Path zipPath = zipfs.getPath("path/into/zip");

Now I have a directory on the local filesystem which I have obtained using:

final Path localDir = Paths.get("/local/dir")

I want to test whether /local/dir/path/into/zip exists, so I check its existence using:

Files.exists(localDir.resolve(zipPath))

but I get a ProviderMismatchException. Why? How do I fix this?

fge
  • 119,121
  • 33
  • 254
  • 329

1 Answers1

17

This behaviour is documented, albeit it is not very visible. You have to delve into the java.nio.file package description to see, right at the end, that:

Unless otherwise noted, invoking a method of any class or interface in this package created by one provider with a parameter that is an object created by another provider, will throw ProviderMismatchException.

The reasons for this behaviour may not be obvious, but consider for instance that two filesystems can define a different separator.

There is no method in the JDK which will help you there. If your filesystems use the same separator then you can work around this using:

path1.resolve(path2.toString())

Otherwise this utility method can help:

public static Path pathTransform(final FileSystem fs, final Path path)
{
    Path ret = fs.getPath(path.isAbsolute() ? fs.getSeparator() : "");
    for (final Path component: path)
        ret = ret.resolve(component.getFileName().toString());
    return ret;
}

Then the above can be written as:

final Path localPath = pathTransform(localDir.getFileSystem(), zipPath);
Files.exists(localDir.resolve(localPath));
fge
  • 119,121
  • 33
  • 254
  • 329
  • I'm unable to get this working. Why is a `component` variable in the loop never used? And you forgot to set return type to `Path` and add brackets after `isAbsolute()` and `getSeparator()`. – Genhis Jul 14 '16 at 19:41
  • So, `ret` is a `Path` of one provider and `path` of another. Then you still get `ProviderMismatchException` if you want to `resolve` them using `component.getFileName()` which returns `Path`, don't you? – Genhis Jul 14 '16 at 22:36
  • 1
    @Genhis *sigh* I forgot `.toString()` after `.getFileName()` – fge Jul 15 '16 at 00:35