NIO2:如何一般地将URI映射到路径? [英] NIO2: how to generically map a URI to a Path?
问题描述
我试图找到一个简单的方法来将一个 URI
映射到一个 Path
任何特定的文件系统。以下似乎工作,但需要一个可疑的技术:
public void process(URI uri)throws IOException {
try {
//首先尝试通过现有文件系统获取路径。 (默认fs)
路径路径= Paths.get(uri);
doSomething(uri,path);
catch(FileSystemNotFoundException e){
//没有现有的文件系统,所以请尝试创建一个。 (罐子,拉链等)
地图< String,?> env = Collections.emptyMap();
try(FileSystem fs = FileSystems.newFileSystem(uri,env)){
Path path = fs.provider()。getPath(uri); // yuck :(
//断言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);
}
在一些示例上运行这段代码会产生如下结果:
$ $ $ $ $ $ $ c $ 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
已被映射到已被植入的 Path
转换成正确的 FileSystem
类型,就像指向jar里面的/ org / foo目录的路径
什么这个代码困扰我,虽然NIO2可以很容易地:
Paths.get(URI)
FileSystem
instance: FileSystems.newFileSystem(uri,env)
...将URI映射到 new FileSystem
实例中的路径没有好的方法。 p>
我能找到的最好的方法就是在创建一个FileSystem之后,我可以让它的 FileSystemProvider
给我Path: p>
Path path = fs.provider()。getPath(uri);
但是这似乎是错误的,因为不能保证它会返回绑定到FileSystem的Path我刚刚实例化(即, path.getFileSystem()== fs
)。它非常依赖于FileSystemProvider的内部状态来知道我指的是哪个FileSystem实例。有没有更好的方法?
Q:我试图找到一个简单的方法来映射一个URI到路径而不写特定于任何特定文件系统的代码
没有这样的方式
整个问题只有在与URI相关的文件系统尚未打开时才有意思,例如,当getFileSystem(在Paths.get中)抛出FileSystemNotFoundException时。
但要调用newFileSystem,您需要知道两件事:
$ ul
所以要从一个URI创建一个新的文件系统,你必须有关于要创建的文件系统的知识。
I'm trying to find an easy way to map a URI
to a Path
without writing code specific to any particular file system. The following seems to work but requires a questionable technique:
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);
}
Running this code on a couple examples produces the following:
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
Notice how the URI
s have been mapped to Path
objects that have been "rooted" into the right kind of FileSystem
, like the Path referring to the directory "/org/foo" inside a jar.
What bothers me about this code is that although NIO2 makes it easy to:
- map a URI to a Path in existing file systems:
Paths.get(URI)
- map a URI to a new
FileSystem
instance:FileSystems.newFileSystem(uri, env)
... there is no nice way to map a URI to a Path in a new FileSystem
instance.
The best I could find was, after creating a FileSystem, I can ask its FileSystemProvider
to give me Path:
Path path = fs.provider().getPath(uri);
But this seems wrong as there is no guarantee it will return a Path that is bound to the FileSystem that I just instantiated (i.e., path.getFileSystem() == fs
). It's pretty much relying on the internal state of FileSystemProvider to know what FileSystem instance I'm referring to. Is there no better way?
Q: "I'm trying to find an easy way to map a URI to a Path without writing code specific to any particular file system"
A: There is no such way
The whole question is only interesting if the filesystem associated with the URI is not open yet, i.e. when getFileSystem (in Paths.get) throws FileSystemNotFoundException. But to call newFileSystem you need to know 2 things:
- what (part of the) URI to use to create the new filesystem. The docu says that i.e. in the case of the default filesystem the path component of the URI must be a root. e.g. getFileSystem( URI.create( "file:///duda", Collections.EMPTY_MAP) fails.
- what to set in the environment map, e.g. might be a password.
So to create a new filesystem from an URI you must have knowledge about the filesystem to create.
这篇关于NIO2:如何一般地将URI映射到路径?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!