如何获取 JAR 包含的类路径中目录中的文件列表?

How do I get the list of files in a directory in a classpath that is included from a JAR?

如何获取 JAR 包含的类路径目录中的文件列表?

问题不在于按字面意思打开 JAR 文件并在其中的目录下查找文件。问题具体是如何列出碰巧在类路径中的目录中的文件,因为 JAR 包含在类路径中。所以不应该涉及打开 JAR 文件。如果这不可能,请解释为什么以及如何在事先不知道 jar 文件名的情况下完成。

假设该项目依赖于另一个资源结构如下的项目:

src/main/resources/testFolder
 - fileA.txt
 - fileB.txt

鉴于 testFolder 在类路径中可用,我该如何枚举其下的文件?

testFolder 最终位于 JAR 中,该 JAR 位于 WAR 的 lib 文件夹中,作为依赖项应位于的位置。

    PathMatchingResourcePatternResolver scanner = new PathMatchingResourcePatternResolver();
    Resource[] resources;
    try {
        resources = scanner.getResources("classpath*:testFolder/**/*.*");
        for (int i = 0; i < resources.length; i++) {
            log.info("resource: {}", resources[i].getFilename() );
        }
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

阅读底层实现后,我发现了以下内容:

URLConnection con = rootDirResource.getURL().openConnection();
JarFile jarFile;
String jarFileUrl;
String rootEntryPath;
boolean newJarFile = false;

if (con instanceof JarURLConnection) {
    // Should usually be the case for traditional JAR files.
    JarURLConnection jarCon = (JarURLConnection) con;
    ResourceUtils.useCachesIfNecessary(jarCon);
    jarFile = jarCon.getJarFile();
    jarFileUrl = jarCon.getJarFileURL().toExternalForm();
    JarEntry jarEntry = jarCon.getJarEntry();
    rootEntryPath = (jarEntry != null ? jarEntry.getName() : "");
}
else {
    // No JarURLConnection -> need to resort to URL file parsing.
    // We'll assume URLs of the format "jar:path!/entry", with the protocol
    // being arbitrary as long as following the entry format.
    // We'll also handle paths with and without leading "file:" prefix.
    String urlFile = rootDirResource.getURL().getFile();
    int separatorIndex = urlFile.indexOf(ResourceUtils.JAR_URL_SEPARATOR);
    if (separatorIndex != -1) {
        jarFileUrl = urlFile.substring(0, separatorIndex);
        rootEntryPath = urlFile.substring(separatorIndex + ResourceUtils.JAR_URL_SEPARATOR.length());
        jarFile = getJarFile(jarFileUrl);
    }
    else {
        jarFile = new JarFile(urlFile);
        jarFileUrl = urlFile;
        rootEntryPath = "";
    }
    newJarFile = true;
}

查看 Spring 的实现,似乎唯一的方法是将资源实际视为 JAR 文件。