列出JAR中的资源文件

时间:2016-08-21 15:53:49

标签: java gradle jar spark-java

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

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

这是当前的代码。它以递归方式列出.sql文件夹中的queries文件,并将其放入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中:在这种情况下,(第1行)始终为null。这是我的胖子配置:

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

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

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

我尝试了什么:

  • /queries更改为queries

  • getResourceAsStream(...)

  • 更改getClassLoader().getResourceAsStream(...)
  • 两个

    我见过this answer,但看起来有点矫枉过正。

帮助表示感谢。谢谢!

1 个答案:

答案 0 :(得分:2)

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

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);
相关问题