我试图找到一种简单的方法来将 a 映射URI
到 aPath
而无需编写特定于任何特定文件系统的代码。以下似乎可行,但需要有问题的技术:
public void process(URI uri) throws IOException {
try {
// First try getting a path via existing file systems. (default fs)
Path path = Paths.get(uri);
doSomething(uri, path);
}
catch (FileSystemNotFoundException e) {
// No existing file system, so try creating one. (jars, zips, etc.)
Map<String, ?> env = Collections.emptyMap();
try (FileSystem fs = FileSystems.newFileSystem(uri, env)) {
Path path = fs.provider().getPath(uri); // yuck :(
// assert path.getFileSystem() == fs;
doSomething(uri, path);
}
}
}
private void doSomething(URI uri, Path path) {
FileSystem fs = path.getFileSystem();
System.out.println(uri);
System.out.println("[" + fs.getClass().getSimpleName() + "] " + path);
}
在几个示例上运行此代码会产生以下结果:
file:/C:/Users/cambecc/target/classes/org/foo
[WindowsFileSystem] C:\Users\cambecc\target\classes\org\foo
jar:file:/C:/Users/cambecc/bin/utils-1.0.jar!/org/foo
[ZipFileSystem] /org/foo
请注意URI
s 是如何映射到Path
已“植根”到正确类型的对象上的FileSystem
,例如引用 jar 中目录“/org/foo”的路径。
这段代码让我困扰的是,尽管 NIO2 很容易:
- 将 URI 映射到现有文件系统中的路径:
Paths.get(URI)
- 将 URI 映射到新
FileSystem
实例:FileSystems.newFileSystem(uri, env)
...没有很好的方法将 URI 映射到新 FileSystem
实例中的路径。
我能找到的最好的方法是,在创建文件系统之后,我可以要求它FileSystemProvider
给我路径:
Path path = fs.provider().getPath(uri);
但这似乎是错误的,因为不能保证它会返回一个绑定到我刚刚实例化的文件系统的路径(即,path.getFileSystem() == fs
)。它非常依赖 FileSystemProvider 的内部状态来知道我指的是什么 FileSystem 实例。没有更好的办法吗?