Java 创建资源路径时从 ZipFileSystemProvider 获取 FileSystemNotFoundException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25032716/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting FileSystemNotFoundException from ZipFileSystemProvider when creating a path to a resource
提问by stevecross
I have a Maven project and inside a method I want to create a path for a directory in my resources folder. This is done like this:
我有一个 Maven 项目,在一个方法中,我想为资源文件夹中的目录创建路径。这是这样做的:
try {
final URI uri = getClass().getResource("/my-folder").toURI();
Path myFolderPath = Paths.get(uri);
} catch (final URISyntaxException e) {
...
}
The generated URI
looks like jar:file:/C:/path/to/my/project.jar!/my-folder
.
生成的URI
看起来像jar:file:/C:/path/to/my/project.jar!/my-folder
.
The stacktrace is as following:
堆栈跟踪如下:
Exception in thread "pool-4-thread-1" java.nio.file.FileSystemNotFoundException
at com.sun.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:171)
at com.sun.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider.java:157)
at java.nio.file.Paths.get(Paths.java:143)
The URI
seems to be valid. The part before !
points to the generated jar-file and the part after it to my-folder
in the root of the archive. I have used this instructions before to create paths to my resources. Why am I getting an exception now?
在URI
似乎是有效的。之前的部分!
指向生成的 jar 文件,之后的部分指向my-folder
存档的根目录。我之前使用过这个说明来创建我的资源的路径。为什么我现在得到一个例外?
采纳答案by Uwe Allner
You need to create the file system before you can access the path within the zip like
您需要先创建文件系统,然后才能访问 zip 中的路径,例如
final URI uri = getClass().getResource("/my-folder").toURI();
Map<String, String> env = new HashMap<>();
env.put("create", "true");
FileSystem zipfs = FileSystems.newFileSystem(uri, env);
Path myFolderPath = Paths.get(uri);
This is not done automatically.
这不是自动完成的。
See http://docs.oracle.com/javase/7/docs/technotes/guides/io/fsp/zipfilesystemprovider.html
请参阅http://docs.oracle.com/javase/7/docs/technotes/guides/io/fsp/zipfilesystemprovider.html
回答by user5922822
If you intend to read the resource file, you can directly use getClass.getResourceAsStream
. This will set up the file system implictly.
The function returns null
if your resource could not be found, otherwise you directly have an input stream to parse your resource.
如果你打算读取资源文件,你可以直接使用getClass.getResourceAsStream
. 这将隐含地设置文件系统。null
如果找不到您的资源,该函数将返回,否则您将直接拥有一个输入流来解析您的资源。
回答by mvreijn
Expanding on @Uwe Allner 's excellent answer, a failsafe method to use is
扩展@Uwe Allner 的优秀答案,使用的故障安全方法是
private FileSystem initFileSystem(URI uri) throws IOException
{
try
{
return FileSystems.getFileSystem(uri);
}
catch( FileSystemNotFoundException e )
{
Map<String, String> env = new HashMap<>();
env.put("create", "true");
return FileSystems.newFileSystem(uri, env);
}
}
Calling this with the URI you are about to load will ensure the filesystem is in working condition.
I always call FileSystem.close()
after using it:
使用您将要加载的 URI 调用此方法将确保文件系统处于工作状态。FileSystem.close()
使用后我总是打电话:
FileSystem zipfs = initFileSystem(fileURI);
filePath = Paths.get(fileURI);
// Do whatever you need and then close the filesystem
zipfs.close();
回答by schlegel11
In addition to @Uwe Allner and @mvreijn:
除了@Uwe Allner 和@mvreijn:
Be careful with the URI
. Sometimes the URI
has a wrong format (e.g. "file:/path/..."
and correct one would be "file:///path/..."
) and you cant get a proper FileSystem
.
In this case it helps that the URI
is created from the Path
's toUri()
method.
小心URI
. 有时候,URI
有一个错误的格式(例如"file:/path/..."
,正确的人会"file:///path/..."
),你不能得到正确的FileSystem
。
在这种情况下,URI
从Path
的toUri()
方法创建 是有帮助的。
In my case I modified initFileSystem
method a little bit and used in non exceptional cases the FileSystems.newFileSystem(uri, Collections.emptyMap())
. In exceptional case the FileSystems.getDefault()
is used.
就我而言,我initFileSystem
稍微修改了方法并在非例外情况下使用了FileSystems.newFileSystem(uri, Collections.emptyMap())
. 在特殊情况下FileSystems.getDefault()
使用 。
In my case it was also necessary to catch the IllegalArgumentException
to handle the case with Path component should be '/'
. On windows and linux the exception is caught but the FileSystems.getDefault()
works. On osx no exception happens and the newFileSystem
is created:
在我的情况下,还需要IllegalArgumentException
使用Path component should be '/'
. 在 windows 和 linux 上,异常被捕获但FileSystems.getDefault()
有效。在 osx 上没有异常发生并且newFileSystem
创建了:
private FileSystem initFileSystem(URI uri) throws IOException {
try {
return FileSystems.newFileSystem(uri, Collections.emptyMap());
}catch(IllegalArgumentException e) {
return FileSystems.getDefault();
}
}