[英]Why can't I access a file within my jar unless I'm in the folder with the Jar when I run it?
[英]Why my Jar doesn't run unless I extract files?
每次我运行导出的.jar
文件(其中包含一个JFrame
带有图像作为其图标)时,该文件都不会运行, 除非我提取该文件 。 在编译器中它正在运行。 我不想创建一个将资源包和jar文件都保存在目录中的启动器。
“为什么除非解压缩文件,否则Jar才会运行?”
这似乎是对资源使用File
的行为。 举个例子
File file = new File("resources/image.png");
Image image = ImagIO.read(file);
和你的项目结构(注意resources
实际上应该是在src
,所以,它建立到罐子自动-除非你将其配置有所不同,但这种说法的缘故,让我们说你 confgigure它在那里resources
是建立在罐)
C:\
Project
resources\image.png
一些检查:
从IDE运行-工作! 为什么? 使用File
在文件系统上查找文件。 使用相对路径,搜索将从“工作目录”开始,对于IDE,通常在项目根目录下进行搜索。 因此, "resources/image.png"
是相对于ProjectRoot
的有效路径
编译jar,说它最终出现在项目的dist
目录中。 这就是它的样子
ProjectRoot dist ProjectRoot.jar
现在,为了这个参数(实际上是正确的方法),让我们尝试在out程序中打印资源的URL,以便当您运行jar时,它会打印文件的URL。
URL url = Test.class.getResource("/resources/image.png"); System.out.println(url.toString());
当我们运行jar C:\\ProjectRoot\\dist> java -jar ProjectRoot.jar
我们将看到打印出来的C:\\ProjectRoot\\dist\\ProjectRoot.jar!\\resources\\image.png
。 您显然可以看到,即使当前的工作目录是jar的位置,路径也不再与添加的jar ProjectRoot.jar!
匹配ProjectRoot.jar!
位置。
那么为什么我们提取它时起作用呢? 好,当您提取它时,路径是正确的
C:\\ProjectRoot dist resources/image.png // from extracted jar ProjectRoot.jar
当您从C:\\ProjectRoot\\dist >
, resource
目录位于应位于的位置。
解释还可以。
因此,当您要读取嵌入式资源时,应从Andrew Thompson提到的URL中读取它们。 该网址应相对于调用它的类或类加载器。 以下是几种不同的方式:
如已显示
URL url = getClass().getResource("/resources/image.png");
注意/
。 这将把我们带到类路径的根目录,即resources
目录。 URL
可以传递给许多构造函数,例如ImageIcon(URL)
或`ImageI.read(URL)
您可以使用:
InputStream is = getClass().getResourceAsStream("/resources/image.png");
它将在后台使用URL。 您还可以将InputStream
与许多构造函数一起使用。
还有一些使用类加载器的方法,该类加载器将从根目录开始,因此您不需要/
URL url = getClass().getClassLoader().getResource("resources/image.png");
因此,有几种方法可以解决此问题。 但是总的来说,使用嵌入式资源时,使用硬编码的字符串路径读取File
从来不是一个好主意。 可以动态获取路径,以便可以使用File
,但是您仍将需要使用上述技术之一,除非您确实需要File
,否则它将是毫无意义的,因为您可以使用InputStream
或URL
这会工作
ProjectRoot
src\resources\image.png
URL url = getClass().getResource("/resources/image.png");
Image image = ImageIO.read(url);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.