列出 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")
我尝试过的:
将 /queries
更改为 queries
将 getResourceAsStream(...)
更改为 getClassLoader().getResourceAsStream(...)
两者
我看过this answer,但看起来有点矫枉过正。
感谢帮助。谢谢!
将目录资源转换为文件。忽略异常,最基本的形式看起来像这样:
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);
我已经迁移了一个 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")
我尝试过的:
将
/queries
更改为queries
将
getResourceAsStream(...)
更改为getClassLoader().getResourceAsStream(...)
两者
我看过this answer,但看起来有点矫枉过正。
感谢帮助。谢谢!
将目录资源转换为文件。忽略异常,最基本的形式看起来像这样:
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);