Java 列出JAR中的资源文件

Java 列出JAR中的资源文件,java,gradle,jar,spark-java,Java,Gradle,Jar,Spark Java,我已经迁移了一个Java项目来使用Gradle,它在IntelliJ或使用命令行时运行良好 但是,当我使用FatJar将其打包到一个独立的JAR中时,我在访问项目的资源时遇到了一些问题 这是当前的代码。它递归地列出查询文件夹中的.sql文件,并将每个文件放入映射中 private static void loadQueriesFrom(final String baseDir) throws IOException { final InputStream is = Queries.cla

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

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

这是当前的代码。它递归地列出
查询
文件夹中的
.sql
文件,并将每个文件放入映射中

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");
这段代码工作正常,除非它打包在一个JAR中:在本例中,is(第1行)始终为空。下面是我的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
因此,查询文件夹包含在JAR中,但由于某些原因,getResourceAsStream无法列出它。但是,它可以访问单个文件。如果插入以下行,则得到预期结果

Queries.class.getResourceAsStream("/queries/collaborators/get_collab_list.sql")
我所尝试的:

  • /查询
    更改为
    查询

  • 通过
    getClassLoader().getResourceAsStream(…)
    更改
    getResourceAsStream(…)

  • 两者

    我见过,但看起来有点过分了


谢谢你的帮助。谢谢

将目录资源转换为文件。忽略异常,其最基本的形式可能如下所示:

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);
    }
}
然后


嘿,您的解决方案不起作用,文件构造函数抛出了一个异常,表示URI无效(不是层次结构)。我已经改变了查询的加载方式(延迟加载+缓存,而不是预加载所有内容)。不过,我会给你奖金,感谢你的回答,因为我无论如何都不能收回它。:-)(虽然我还不能给出赏金)看看这个答案:但与其将其转换为文件,不如使用URL.openStream流读取内容。
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);