我有一个Maven项目,在一个方法中我想为我的资源文件夹中的目录创建一个路径。这是这样做的:
try {
final URI uri = getClass().getResource("/my-folder").toURI();
Path myFolderPath = Paths.get(uri);
} catch (final URISyntaxException e) {
...
}
生成的URI
看起来像jar:file:/C:/path/to/my/project.jar!/my-folder
。
堆栈跟踪如下:
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)
URI
似乎有效。 !
之前的部分指向生成的jar文件,后面的部分指向归档根目录中的my-folder
。我之前使用过这些说明来创建资源的路径。为什么我现在得到例外?
答案 0 :(得分:47)
您需要先创建文件系统,然后才能访问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);
这不是自动完成的。
请参阅http://docs.oracle.com/javase/7/docs/technotes/guides/io/fsp/zipfilesystemprovider.html
答案 1 :(得分:8)
如果您打算阅读资源文件,可以直接使用getClass.getResourceAsStream
。这将隐含地设置文件系统。
如果找不到您的资源,该函数将返回null
,否则您将直接拥有一个输入流来解析您的资源。
答案 2 :(得分:6)
扩展@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);
}
}
使用您要加载的URI调用此方法将确保文件系统处于工作状态。
使用后我总是打电话给FileSystem.close()
:
FileSystem zipfs = initFileSystem(fileURI);
filePath = Paths.get(fileURI);
// Do whatever you need and then close the filesystem
zipfs.close();
答案 3 :(得分:4)
除了@Uwe Allner和@mvreijn:
小心URI
。有时,URI
格式错误(例如"file:/path/..."
,而正确的格式为"file:///path/..."
),您无法获得正确的FileSystem
。
在这种情况下,从URI
的{{1}}方法创建Path
会有所帮助。
在我的例子中,我稍微修改了toUri()
方法,并在非特殊情况下使用了initFileSystem
。在特殊情况下,使用FileSystems.newFileSystem(uri, Collections.emptyMap())
。
在我的情况下,还有必要抓住FileSystems.getDefault()
来处理IllegalArgumentException
的案例。在Windows和Linux上捕获异常,但Path component should be '/'
有效。在osx上没有异常发生并且FileSystems.getDefault()
被创建:
newFileSystem