java-如何正确引用资源文件进行JAR和调试?

使用Maven项目和Jar文件时,在引用资源时遇到麻烦的问题...

我将所有资源都放在一个专用文件夹/ src / main / resources中,该文件夹是Eclipse中构建路径的一部分。 使用以下文件引用文件

getClass().getResource("/filename.txt")

这在Eclipse中工作正常,但在Jar文件中失败-资源位于jar根目录正下方的文件夹中...

有谁知道在JAR和Eclipse中同时引用文件的“最佳实践”?

编辑:问题是,虽然资源实际上位于顶层文件夹“ resources”中的JAR中,但上述方法无法找到该文件...


7个解决方案

19 votes

Maven资源文件夹的内容被复制到目标/类,并从那里复制到生成的Jar文件的根目录。 那是预期的行为。

我不明白的是您的方案中存在的问题。 通过ThatClass.class.getResource("/path/with/slash")引用资源始于类路径的根,无论该路径(或其元素)是ThatClass.class.getClassLoader().getResource("path/without/slash")还是JAR的根。 我看到的唯一可能的错误是您使用的是错误的ClassLoader。

确保使用资源的类与资源在同一工件(JAR)中,然后执行ThatClass.class.getResource("/path/with/slash")或ThatClass.class.getClassLoader().getResource("path/without/slash")。

但除此之外:如果它不起作用,则可能是在构建过程中某处做错了。 您可以验证资源是否在JAR中?

Sean Patrick Floyd answered 2020-08-04T21:15:59Z

18 votes

我有一个类似的问题。经过一整天的尝试每种组合和调试,我尝试了getClass()。getResourceAsStream(“ resources / filename.txt”)并使其最终起作用。没有其他帮助。

andjelko answered 2020-08-04T21:16:19Z

18 votes

打包JAR后,您的资源文件不再是文件,而是流文件,因此getResourceAsStream将无法工作!

使用getResourceAsStream。

要获取“文件”内容,请使用[https://commons.apache.org/proper/commons-io/javadocs/api-release/org/apache/commons/io/IOUtils.html:]
static public String getFile(String fileName)
{
//Get file from resources folder
ClassLoader classLoader = (new A_CLASS()).getClass().getClassLoader();
InputStream stream = classLoader.getResourceAsStream(fileName);
try
{
if (stream == null)
{
throw new Exception("Cannot find file " + fileName);
}
return IOUtils.toString(stream);
}
catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
return null;
}
Thomas Decaux answered 2020-08-04T21:16:48Z
-1 votes
如果将资源目录添加到jar文件中(因此它位于jar的/ resources文件夹下,并且/ src / main在eclipse中的构建路径中,那么您应该能够以以下方式引用文件:
getClass().getResource("/resources/filename.txt");
在两种环境下都应该工作。
Steven Mastandrea answered 2020-08-04T21:17:12Z
-1 votes
也许这种方法可以在某些情况下有所帮助。
public static File getResourceFile(String relativePath)
{
File file = null;
URL location = .class.getProtectionDomain().getCodeSource().getLocation();
String codeLocation = location.toString();
try{
if (codeLocation.endsWith(".jar"){
//Call from jar
Path path = Paths.get(location.toURI()).resolve("../classes/" + relativePath).normalize();
file = path.toFile();
}else{
//Call from IDE
file = new File(.class.getClassLoader().getResource(relativePath).getPath());
}
}catch(URISyntaxException ex){
ex.printStackTrace();
}
return file;
}
gbii answered 2020-08-04T21:17:32Z
-2 votes

问题是在IDE中,getClass()。getResource(“ Path”); 访问文件时,字符串不区分大小写,但是从jar运行时,字符串不区分大小写。 检查目录和文件的大小写。 确实有效。 另外,如果您尝试新的File(getClass()。getResource(“ Path”);则在IDE外部将无法读取该文件。

Christo Naudé answered 2020-08-04T21:17:53Z
-4 votes
只需将文件复制到临时目录即可。
String tempDir = System.getProperty("java.io.tmpdir");
File file = new File(tempDir.getAbsolutePath(), "filename.txt");
if (!file.exists()) {
InputStream is = (getClass().getResourceAsStream("/filename.txt"));
Files.copy(is, file.getAbsoluteFile().toPath());
}
Juangui Jordán answered 2020-08-04T21:18:12Z