在 JDK 12 之前,内置中不支持嵌套 jar 文件ZipFileSystem
at all.
例如,newFileSystem
的方法ZipFileSystemProvider
接受一个Path
有这样的声明
if (path.getFileSystem() != FileSystems.getDefault()) {
throw new UnsupportedOperationException();
}
即使对于 JDK 12,由于一贯的虐待,掌握嵌套 zip 文件系统也不是一件容易的事jar:
URLs.
语法为jar:
URLs 已指定 as:
jar:<url>!/{entry}
这意味着您的资源的正确 URL 是
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,您必须使用第一个 URL 之间的部分来提取 jar 文件的位置jar:
和最后一个!/
并递归地解析它。
然而,我见过的所有 JDK 代码,无论是否支持URL
API 或FileSystem
API 始终无法做到这一点,使用indexOf("!/")
而不是lastIndexOf("!/")
。
如此嵌套jar:
URI/URL 根本不起作用。
获得嵌套文件系统的唯一方法是使用以下命令打开它们Path
实例已与某个关联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 或更高版本。