java - 在嵌套 JAR 内的文件夹中查找文件名

标签 java java-8

当我的应用程序打包为 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 文件。

例如,ZipFileSystemProvidernewFileSystem 方法接受 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/

相关文章:

java - Maven 根据配置文件更新属性

Java 8 在给定一组有序键的情况下按键对映射进行排序

java-8 - 如何将列表转换为 Map<K,V> 而不是 List<V>

java - 如何根据给定模式重新排列列表中的项目?

java - 如何找到一部分网格的坐标?

java - 如何获取用于日志记录的kafka consumer-id

java - 我是否可以通过任何方式重写 Integer 和 String 类的 equals/compare 方法?

spring - Reactor Mono 与 CompletableFuture

java - jcifs.smb.SmbAuthException : Logon failure: unknown user name or bad password. 错误

java - 瓦片 map 中的命中检测