我创建了一个基于maven的java项目,该项目有资源目录(src/java/resources),其中一些xml文件和maven将它们复制到目标/类/资源(目标/类是我的类路径)。
要了解xml文件的内容,使用:
new FileInputStream(Main.class.getClassLoader().getResource("Configuration.xml").getPath());
Main.class.getClassLoader(). getresource ("Configuration.xml"). getpath()给了我xml的完整路径:"c:project…Configuration.xml"。
这在intelllij上运行良好。
,但当我编译和打包项目到一个jar文件,我得到:
Exception in thread "main" java.io.FileNotFoundException:
file:C:projecttargetproject-12.50.14-SNAPSHOT-jar-with-dependencies
.jar!Configuration.xml
(The filename, directory name, or volume label syntax is incorrect)
这是因为路径: C:projecttargetproject-12.50.14- snapshot -jar-with-dependenciesConfiguration.xml不能作为FileInputStream()的参数。
我不能将getResource()替换为getresourcesstream()。
我需要一种方法来调整我的jar和资源,使其像在智能j上一样工作。我还在运行时更改了xml资源文件的内容,这是将它们保存在jar中的另一个问题。
谁能给我一个解决方案,我不需要改变我的代码,而是改变我的资源目录结构,或改变类路径,或其他东西,将保持我的代码工作?谢谢。
更新:更改为使用File
,而不是Path
。
这是因为getResource
返回URL
,而不是所有的url都是磁盘上的文件,即可以转换为Path
。正如javadoc所说:"返回[…]如果[路径部分]不存在,则为空字符串"。
如果绝对必须是File
或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并且总是需要副本,所以在开发模式下使用copy可以帮助测试代码。