从 jar 中读取资源文件

2022-08-31 05:03:02

我想从我的罐子里读一个资源,就像这样:

File file;
file = new File(getClass().getResource("/file.txt").toURI());
BufferedReader reader = new BufferedReader(new FileReader(file));

//Read the file

在Eclipse中运行它时它工作正常,但是如果我将其导出到jar中,然后运行它,则会出现一个TraveralArgumentException:

Exception in thread "Thread-2"
java.lang.IllegalArgumentException: URI is not hierarchical

我真的不知道为什么,但通过一些测试,我发现如果我改变

file = new File(getClass().getResource("/file.txt").toURI());

file = new File(getClass().getResource("/folder/file.txt").toURI());

然后它的工作原理相反(它在罐子中工作,但不在日食中工作)。

我正在使用Eclipse,并且带有我的文件的文件夹位于类文件夹中。


答案 1

与其尝试将资源作为文件寻址不如要求 ClassLoader 通过 getResourceAsStream 返回资源的 InputStream

try (InputStream in = getClass().getResourceAsStream("/file.txt");
    BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
    // Use resource
}

只要资源在类路径上可用,那么无论资源是在目录中还是在 .file.txtfile.txtclasses/jar

发生这种情况是因为 jar 文件中资源的 URI 将如下所示:。您不能像读取普通的旧文件一样读取(文件)中的条目。URI is not hierarchicalfile:/example.jar!/file.txtjarzip

这可以通过以下答案很好地解释:


答案 2

要访问 jar 中的文件,您有两个选择:

  • 将文件放在与您的包名称匹配的目录结构中(提取.jar文件后,它应该与.class文件位于同一目录中),然后使用getClass().getResourceAsStream("file.txt")

  • 将文件放在根目录下(提取.jar文件后,它应该在根目录中),然后使用Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt")

当 jar 用作插件时,第一个选项可能不起作用。