Java 在嵌套JAR中的文件夹中查找文件名

Java 在嵌套JAR中的文件夹中查找文件名,java,java-8,Java,Java 8,当我的应用程序打包为JAR时,我很难到达目标文件夹“images”。 我不是在得到一个文件之后,我想要的是“images”文件夹中所有.jpg文件的列表 我试过这个: URI=getClass().getClassLoader.getResource(“图像”).toURI() 这将返回:jar:file:/C:/test-1.0-SNAPSHOT.jar/BOOT-INF/lib/core-1.0-SNAPSHOT.jar/图像 然后,我尝试创建一个流来迭代文件,如下所示: FileSyste

当我的应用程序打包为JAR时,我很难到达目标文件夹“images”。 我不是在得到一个文件之后,我想要的是“images”文件夹中所有.jpg文件的列表

我试过这个: URI=getClass().getClassLoader.getResource(“图像”).toURI()

这将返回:
jar:file:/C:/test-1.0-SNAPSHOT.jar/BOOT-INF/lib/core-1.0-SNAPSHOT.jar/图像

然后,我尝试创建一个流来迭代文件,如下所示:

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”文件夹呢


编辑:这不是的重复项:。我试过里面的每一样东西。不同的是我在另一个罐子里有一个罐子,嵌套的罐子。我相信这就是造成问题的原因。

在JDK 12之前,内置
ZipFileSystem
中根本不支持嵌套jar文件

例如,
ZipFileSystemProvider
接受路径的
newFileSystem
方法有如下语句

if (path.getFileSystem() != FileSystems.getDefault()) {
    throw new UnsupportedOperationException();
}
即使对于JDK12来说,也不容易接触到嵌套的zip文件系统,因为
jar:
URL总是被错误对待

jar:
URL的语法如下:

要解析这样的URL,您必须使用第一个
jar:
和最后一个
之间的部分来提取jar文件的位置/并递归地解析它。
然而,我所看到的所有JDK代码,无论是支持
URL
API还是支持
文件系统
API,都始终无法做到这一点,使用
indexOf(!/”
而不是
lastinexof(!/”
)。 所以嵌套的
jar:
uri/url根本不起作用

获得嵌套文件系统的唯一方法是使用已与
文件系统关联的
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或更高版本。

我写了一个答案,但没有及时发布。你可以在这里看到:@lino说restore monica你能移除重复的标签吗,因为这是错误的?谢谢,是的,我在JDK 8上尝试了你的上一个建议,只是在那里抛出了一个
ProviderNotFoundException
:(.通过在txt文件中列出我需要的文件名来解决问题。虽然不漂亮,但它工作良好是的,
FileSystems.newFileSystem
将迭代安装的提供程序,探测它们并捕获
UnsupportedOperationException
,继续迭代,最终说没有找到匹配的提供程序ound.您可以手动迭代提供程序,找到正确的提供程序并请求它创建一个新的文件系统;这就是我发现它抛出一个
不支持操作异常的原因…
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
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));
}