列出 JAR 中的资源文件

Listing resource files from a JAR

我已经迁移了一个 Java 项目以使用 Gradle,它在 IntelliJ 或使用命令行中工作得很好。

但是,当我使用 FatJar 将它打包到一个独立的 JAR 中时,我在访问我的项目的资源时遇到了一些问题。

这是当前代码。它以递归方式列出 queries 文件夹中的 .sql 文件,并将每个文件放入 Map 中。

private static void loadQueriesFrom(final String baseDir) throws IOException {
    final InputStream is = Queries.class.getResourceAsStream(baseDir);

    if (is == null)
        return;
    
    List<String> queryFiles = IOUtils.readLines(is, Charsets.UTF_8);
    
    for (String queryFile: queryFiles) {
        final int index = queryFile.lastIndexOf(".sql");
        
        if (index == -1) {
            loadQueriesFrom(baseDir + queryFile + "/"); // directory
        }
        else {
            final String queryName = queryFile.substring(0, index).toLowerCase();

            queries.put(baseDir.substring(QUERY_DIRECTORY.length()) + queryName, IOUtils.toString(Queries.class
                    .getResourceAsStream(baseDir + queryFile)));

        }
    }
       
}

// First call is
loadQueriesFrom("/queries");

我的目录结构如下:

- src
  - main
      - java
      - resources
          - queries
  - test

这段代码工作正常,除非它被打包在 JAR 中:在这种情况下,is(第 1 行)始终为 null。这是我的 fatjar 配置:

task fatjar(type: Jar) {
    baseName = project.name
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    with jar
    manifest {
        attributes 'Implementation-Title': 'My project name', 'Implementation-Version': version
        attributes 'Main-Class': 'org.mypackage.MyMainClass'
    }
}

如果我打开生成的 .jar 文件,结构如下所示

- org
    - mypackage
        ...
- queries

因此 queries 文件夹 包含在 JAR 中,但由于某些原因 getResourceAsStream 可以列出来。但是,它可以访问单个文件。如果我插入以下行,我会得到预期的结果。

Queries.class.getResourceAsStream("/queries/collaborators/get_collab_list.sql")

我尝试过的:

感谢帮助。谢谢!

将目录资源转换为文件。忽略异常,最基本的形式看起来像这样:

URL url = Queries.class.getResource("/queries");
File dir = new File(url.toURI());
for (File file : dir.listFiles()) {
    // do something with file
}

如果要递归文件树:

void doSomething(File file) {
    // do something with file
}

void processFile(File file) {
    if (file.isDirectory()) {
        for (File sub : file.listFiles()) {
            processFile(sub);
        }
    } else {
        doSomething(file);
    }
}

然后

URL url = Queries.class.getResource("/queries");
File dir = new File(url.toURI());
processFile(dir);