我已将所有 JavaFX 代码放入可执行 JAR 文件中。一切都在里面。
当我使用 Eclipse IDE 编译它时,它可以工作,但是当我尝试执行 JAR 文件时,出现错误。
Caused by: javafx.fxml.LoadException:
file:/home/asus/program/JUSBPlotter/JUSBPlotter-0.0.1-SNAPSHOT-jar-with-dependencies.jar!/se/danielmartensson/fxml/front.fxml
当我有这个Java代码时
Parent root = FXMLLoader.load(getClass().getResource("/se/danielmartensson/fxml/front.fxml"));
FXML 文件没有任何问题。
fx:controller="se.danielmartensson.controller.Front"
当我尝试在 JavaFX 中显示图片时,我也遇到错误。
Caused by: java.io.FileNotFoundException: file:/home/asus/program/JUSBPlotter/JUSBPlotter-0.0.1-SNAPSHOT-jar-with-dependencies.jar!/se/danielmartensson/pictures/computer.png (No such file or directory)
当我有这个 Java 代码时:
FileInputStream picture1 = new FileInputStream(getClass().getResource("/se/danielmartensson/pictures/computer.png").getFile());
问题: 如何告诉 Java JAR 文件中正确的文件路径?
最佳答案
要记住的一件事是,资源与文件不同,尽管它们看起来非常相似——尤其是在打包应用程序之前。一旦打包应用程序,这些资源文件就会成为 JAR 文件中的条目,虽然它们可以被视为文件,但不能像文件一样进行访问。特别是java.io.File
API 不知道如何读取这些条目。但是,您可以通过URL
访问这些条目。返回者 Class#getResource(String)
或InputStream
返回者 Class#getResourceAsStream(String)
。请注意,后者基本上只是找到 URL
并且,如果存在,则调用 URL#openStream()
。您可以使用 URL
访问 JAR 条目(即资源)的原因是由于 JarURLConnection
及相关类(class);我不会详细介绍 Java 如何处理 URL,因为这超出了本答案的范围。
现在,由于您尝试在 JavaFX 中显示图像,我假设您正在使用 Image
类(class)。基本上可以通过三种方式来辨别 Image
图片资源在哪里。
使用
Image#<init>(String)
其中参数 URL 没有方案。在这种情况下,类会将 URL 视为相对于类路径根的路径,并尝试相应地访问图像。基本上,该参数与您为Class#getResource(String)
提供的参数相同。 ,但路径必须是绝对路径(即不相对于任何类)。Image
记录了此行为类:All URLs supported by
URL
can be passed to the constructor. If the passed string is not a valid URL, but a path instead, the Image is searched on the classpath in that case.注意:如果您使用模块,则 resource encapsulation使用此选项时发挥作用。请参阅GitHub Issue #441 .
使用与上面相同的构造函数,但传递一个有效的 URL(即它有一个方案)。使用资源时,只需将
URL
转换即可返回者Class#getResource(Sring)
进入String
使用URL#toExternalForm()
.Image image = new Image(getClass().getResource(...).toExternalForm());
注意:您还可以使用
URL#toString()
返回相同的值。使用
Image#<init>(InputStream)
。这里你可以使用Class#getResourceAsStream(String)
。不要忘记关闭InputStream
完成后。try (InputStream is = getClass().getResourceAsStream(...)) { Image image = new Image(is); }
所有这些都假设您在构建 JAR 文件时已将资源正确打包到该文件中。如果不是这种情况,请先遵循 José Pereda 在问题评论中给出的建议。
<小时/>请注意,可以使用 java.util.zip.*
访问 ZIP/JAR 文件的条目。 API,java.util.jar.*
API,或 Java NIO 的 ZipFileSystemProvider
。其中每个选项(尤其是最后一个选项)都允许您像实际文件一样访问 ZIP/JAR 文件的条目,因为它们是专门为此设计的。但是,在应用程序中使用资源时,您应该坚持使用 Class#getResource(String)
以及相关方法。
关于java - 如何告诉 Java JAR 文件中正确的文件路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56386935/