在嵌套JAR内的文件夹中查找文件名
当我的应用程序打包为JAR时,我无法到达目标文件夹"images". 我得到的不是单个文件,我想要的是图像"文件夹中所有.jpg文件的列表.
I'm having trouble reaching a target folder "images" when my application is packaged as a JAR. I am not after getting a single file, what I want is a list of all the .jpg files in the "images" folder.
我已经尝试过了:
URI uri = getClass().getClassLoader.getResource("images").toURI();
这将返回:jar:file:/C:/test-1.0-SNAPSHOT.jar!/BOOT-INF/lib/core-1.0-SNAPSHOT.jar!/images
然后,我尝试创建一个流来迭代这样的文件:
Then i tried to create a stream to iterate over the files like this:
FileSystem fs = FileSystems.newFilesSystem(uri, Collections.emptyMap());
Path p = fs.getPath("images");
Files.walk(p).forEach(path -> System.out.println(path));
这只是给med一个FileNotFoundException.
This just gives med a FileNotFoundException.
那么,如何访问嵌套JAR内的"images"文件夹?
So, how can I access the "images" folder inside my nested JARs?
这不是以下内容的重复:如何列出JAR文件中的文件?.我已经尝试了所有的东西.不同之处在于我在另一个JAR(嵌套JAR)中有一个JAR.这就是造成我相信的问题的原因.
This is not duplicate of: How to list the files inside a JAR file?. I have tried every thing in there. The difference is that i have a JAR INSIDE another JAR, nested JARs. This is what is creating the issue i believe.
在JDK 12之前,完全不支持内置ZipFileSystem
中的嵌套jar文件.
Prior to JDK 12, there is no support for nested jar files in the builtin ZipFileSystem
at all.
例如,ZipFileSystemProvider
接受Path
的newFileSystem
方法具有类似
E.g., the newFileSystem
method of ZipFileSystemProvider
accepting a Path
has a statement like
if (path.getFileSystem() != FileSystems.getDefault()) {
throw new UnsupportedOperationException();
}
即使对于JDK 12,由于对jar:
URL的持续误操作,获取嵌套zip文件系统也不容易.
Even for JDK 12, getting hands on nested zip filesystems is not easy due to a consistent mistreatment of jar:
URLs.
jar:
URL的语法已指定为:
jar:<url>!/{entry}
这意味着您资源的正确URL将是
which implies that the correct URL for your resource would be
outer file file:/C:/test-1.0-SNAPSHOT.jar
nested jar file jar:file:/C:/test-1.0-SNAPSHOT.jar!/BOOT-INF/lib/core-1.0-SNAPSHOT.jar
entry of nested jar:jar:file:/C:/test-1.0-SNAPSHOT.jar!/BOOT-INF/lib/core-1.0-SNAPSHOT.jar!/images
要解析这样的URL,您必须使用第一个jar:
和最后一个!/
之间的部分提取jar文件的位置,然后递归地对其进行解析.
但是,我见过的所有JDK代码,无论是支持URL
API还是FileSystem
API都始终失败,使用indexOf("!/")
而不是lastIndexOf("!/")
.
因此,嵌套的jar:
URI/URL根本不起作用.
To parse such a URL, you would have to extract the location of the jar file using the part between the first jar:
and the last !/
and recursively parse that.
However, all JDK code I’ve seen, regardless of backing the URL
API or the FileSystem
API consistently fails to do so, using indexOf("!/")
rather then lastIndexOf("!/")
.
So nested jar:
URIs/URLs simply don’t work.
使用嵌套文件系统的唯一方法是使用已经与FileSystem
关联的Path
实例打开它们:
The only way to get hands on a nested file system is to open them using Path
instances already associated with a FileSystem
:
Path outer = Paths.get("C:", "test-1.0-SNAPSHOT.jar");
ClassLoader cl = null;
try(FileSystem outerFs = FileSystems.newFileSystem(outer, cl);
FileSystem innerFs = FileSystems.newFileSystem(
outerFs.getPath("/BOOT-INF/lib/core-1.0-SNAPSHOT.jar"), cl) ) {
Path p = innerFs.getPath("images");
Files.walk(p).forEach(path -> System.out.println(path));
}
这适用于JDK12或更高版本.
This works with JDK12 or newer.