当我的应用程序打包为 JAR 时,我无法访问目标文件夹“images”。 我不是在获取单个文件,我想要的是“images”文件夹中所有 .jpg 文件的列表。
我已经尝试过这个:
URI uri = getClass().getClassLoader.getResource("images").toURI();
这将返回:jar:file:/C:/test-1.0-SNAPSHOT.jar!/BOOT-INF/lib/core-1.0-SNAPSHOT.jar!/images
然后我尝试创建一个流来迭代文件,如下所示:
FileSystem fs = FileSystems.newFilesSystem(uri, Collections.emptyMap());
Path p = fs.getPath("images");
Files.walk(p).forEach(path -> System.out.println(path));
这只会给 med 一个 FileNotFoundException。
那么,如何访问嵌套 JAR 中的“images”文件夹?
编辑:这不重复:How to list the files inside a JAR file? 。我已经尝试了那里的一切。不同之处在于我有一个 JAR 位于另一个 JAR 中,即嵌套 JAR。我认为这就是造成问题的原因。
最佳答案
在 JDK 12 之前,内置 ZipFileSystem
中根本不支持嵌套 jar 文件。
例如,ZipFileSystemProvider
的 newFileSystem
方法接受 Path
的语句如下
if (path.getFileSystem() != FileSystems.getDefault()) {
throw new UnsupportedOperationException();
}
即使对于 JDK 12,由于对 jar:
URL 的一贯错误处理,掌握嵌套 zip 文件系统也并不容易。
jar:
URL 的语法 has been specified如:
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,您必须使用第一个 jar:
和最后一个 !/
之间的部分提取 jar 文件的位置,并递归解析那。
但是,我见过的所有 JDK 代码,无论支持 URL
API 还是 FileSystem
API,都始终无法使用 indexOf("!/")
而不是 lastIndexOf("!/")
。
所以嵌套的 jar:
URI/URL 根本不起作用。
获取嵌套文件系统的唯一方法是使用已与 FileSystem
关联的 Path
实例打开它们:
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 或更高版本。
关于java - 在嵌套 JAR 内的文件夹中查找文件名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58976001/