0

我创建了一个基于 maven 的 java 项目,该项目具有资源目录 (src/java/resources),其中一些 xml 文件和 maven 将它们复制到 target/classes/resources (target/classes 是我的类路径)。

要了解 xml 文件的内容,我使用:

new FileInputStream(Main.class.getClassLoader().getResource("Configuration.xml").getPath());

Main.class.getClassLoader().getResource("Configuration.xml").getPath() 为我提供了 xml 的完整路径:“c:\project...\Configuration.xml”。

这在 intellij 上效果很好。

但是当我将项目编译并打包成一个 jar 文件时,我得到:

Exception in thread "main" java.io.FileNotFoundException: 
file:\C:\project\target\project-12.50.14-SNAPSHOT-jar-with-dependencies
.jar!\Configuration.xml 

(The filename, directory name, or volume label syntax is incorrect)

那是因为路径:\C:\project\target\project-12.50.14-SNAPSHOT-jar-with-dependencies .jar!\Configuration.xml 不能作为 FileInputStream() 的参数。

我无法将 getResource() 替换为 getResourceAsStream()。

我需要一种方法来调整我的 jar 和资源,使其像在 intellij 上一样工作。我还在运行时更改了 xml 资源文件的内容,因此将它们保存在 jar 中是另一个问题。

谁能给我一个解决方案,我不必更改我的代码,而是更改我的资源目录结构,或更改类路径,或者其他可以让我的代码正常工作的东西?谢谢。

4

1 回答 1

0

更新:改为使用File,不是Path

那是因为getResource返回 a URL,并不是所有的 url 都是磁盘上的文件,即可以转换为 a Path。正如javadoc所说“如果[路径部分]不存在,则返回[...]一个空字符串”。

如果它绝对必须Fileor FileInputStream,因为您无法更改的某些其他代码需要它,则将内容复制到临时文件:

File file = File.createTempFile("Configuration", ".xml");
try {
    try {InputStream in = Main.class.getClassLoader().getResourceAsStream("Configuration.xml")) {
        Files.copy(in, file.toPath()); // requires Java 7
    }
    // use file here, or:
    try {FileInputStream in = new FileInputStream(file)) {
        // use file stream here
    }
} finally {
    file.delete();
}

如果资源是文件,上面的代码可以优化为不复制,但由于这仅适用于开发模式,而生产模式始终是 Jar 并且总是需要副本,因此在开发模式下使用复制有助于测试代码。

于 2015-08-27T16:16:31.633 回答