特定のファイル システムに固有のコードを記述せずに、aURI
を aにマップする簡単な方法を見つけようとしています。Path
以下は機能しているように見えますが、疑わしいテクニックが必要です。
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
jar 内のディレクトリ「/org/foo」を参照する Path のように、適切な種類の に「ルート化」されたオブジェクトにがどのようURI
にマップされているかに注目してください。Path
FileSystem
このコードについて私が気になるのは、NIO2 を使用すると次のことが簡単になることです。
- URI を既存のファイル システム のパスにマップします。
Paths.get(URI)
- URI を新しい
FileSystem
インスタンス にマップします。FileSystems.newFileSystem(uri, env)
...新しい FileSystem
インスタンスで URI をパスにマップする良い方法はありません。
私が見つけた最良の方法は、ファイルシステムを作成した後、パスを提供するように頼むことができるということでしたFileSystemProvider
:
Path path = fs.provider().getPath(uri);
しかし、インスタンス化したばかりの FileSystem (つまりpath.getFileSystem() == fs
) にバインドされたパスを返す保証がないため、これは間違っているようです。私が参照している FileSystem インスタンスを知るには、FileSystemProvider の内部状態にほとんど依存しています。もっと良い方法はありませんか?