jar 中的 Java 访问文件导致 java.nio.file.FileSystemNotFoundException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22605666/
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
Java access files in jar causes java.nio.file.FileSystemNotFoundException
提问by tom91136
While trying to copy some files in my jar file to a temp directory with my java app, the following exception is thrown:
尝试使用我的 java 应用程序将 jar 文件中的某些文件复制到临时目录时,抛出以下异常:
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(Unknown Source)
at com.sora.util.walltoggle.pro.WebViewPresentation.setupTempFiles(WebViewPresentation.java:83)
....
and this is a small part of my setupTempFiles
(with line numbers):
这是我的一小部分setupTempFiles
(带有行号):
81. URI uri = getClass().getResource("/webViewPresentation").toURI();
//prints: URI->jar:file:/C:/Users/Tom/Dropbox/WallTogglePro.jar!/webViewPresentation
82. System.out.println("URI->" + uri );
83. Path source = Paths.get(uri);
the webViewPresentation
directory resides in the root directory of my jar:
该webViewPresentation
目录位于我的 jar 的根目录中:
This problem only exits when I package my app as a jar, debugging in Eclipse has no problems. I suspect that this has something to do with this bugbut I'm not sure how to correct this problem.
只有当我将我的应用程序打包为 jar 时才会出现此问题,在 Eclipse 中调试没有问题。我怀疑这与此错误有关,但我不确定如何更正此问题。
Any helps appreciated
任何帮助表示赞赏
If matters:
如果重要:
I'm on Java 8 build 1.8.0-b132
我在 Java 8 build 1.8.0-b132
Windows 7 Ult. x64
Windows 7 终极版 x64
采纳答案by fge
A FileSystemNotFoundException
means the file system cannot be created automatically; and you have not created it here.
AFileSystemNotFoundException
表示无法自动创建文件系统;你还没有在这里创建它。
Given your URI, what you should do is split against the !
, open the filesystem using the part before it and then get the path from the part after the !
:
给定您的 URI,您应该做的是拆分!
,使用它之前的部分打开文件系统,然后从 之后的部分获取路径!
:
final Map<String, String> env = new HashMap<>();
final String[] array = uri.toString().split("!");
final FileSystem fs = FileSystems.newFileSystem(URI.create(array[0]), env);
final Path path = fs.getPath(array[1]);
Note that you should .close()
your FileSystem
once you're done with it.
请注意,您应该.close()
你FileSystem
一旦你用它做。
回答by hemanto
If you're using spring framework library, then there is an easy solution for it.
如果您使用的是 spring 框架库,那么有一个简单的解决方案。
As per requirement we want to read webViewPresentation; I could solve the same problem with below code:
根据要求,我们要阅读 webViewPresentation;我可以用下面的代码解决同样的问题:
URI uri = getClass().getResource("/webViewPresentation").toURI();
FileSystems.getDefault().getPath(new UrlResource(uri).toString());
回答by Kinmarui
Accepted answer isn't the best since it doesn't work when you start application in IDE or resource is static and stored in classes! Better solution was proposed at java.nio.file.FileSystemNotFoundException when getting file from resources folder
接受的答案不是最好的,因为当您在 IDE 中启动应用程序或资源是静态的并存储在类中时它不起作用!从资源文件夹中获取文件时,在java.nio.file.FileSystemNotFoundException中提出了更好的解决方案
InputStream in = getClass().getResourceAsStream("/webViewPresentation");
byte[] data = IOUtils.toByteArray(in);
IOUtils is from Apache commons-io.
IOUtils 来自 Apache commons-io。
But if you are already using Spring and want a text file you can change the second line to
但是如果你已经在使用 Spring 并且想要一个文本文件,你可以将第二行更改为
StreamUtils.copyToString(in, Charset.defaultCharset());
StreamUtils.copyToByteArray also exists.
StreamUtils.copyToByteArray 也存在。
回答by fuemf5
This is maybe a hack, but the following worked for me:
这可能是一个黑客,但以下对我有用:
URI uri = getClass().getResource("myresourcefile.txt").toURI();
if("jar".equals(uri.getScheme())){
for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
if (provider.getScheme().equalsIgnoreCase("jar")) {
try {
provider.getFileSystem(uri);
} catch (FileSystemNotFoundException e) {
// in this case we need to initialize it first:
provider.newFileSystem(uri, Collections.emptyMap());
}
}
}
}
Path source = Paths.get(uri);
This uses the fact that ZipFileSystemProvider internally stores a List of FileSystems that were opened by URI.
这使用了 ZipFileSystemProvider 在内部存储由 URI 打开的文件系统列表的事实。