Java编译成jar后getResource()出错
Java error getResource() after compilation into jar
昨天我终于完成了我的 JavaFX 应用程序,它在 IDE 中完美地 运行,但是当我试图将它转换为 .jar
文件然后 运行 时。 .. 它没有用。我发现我的 class 无法使用 getClass().getResource()
导入任何 .fxml
文件。
所以我创建了一个示例代码,它试图读取文本文件 CheckFile.txt
。
Class路径树:
.
├── ClassFileTry.iml
├── out
│ ├── artifacts
│ │ └── ClassFileTry_jar
│ │ └── ClassFileTry.jar
│ └── production
│ └── ClassFileTry
│ ├── com
│ │ └── company
│ │ ├── CheckFile.txt
│ │ └── Main.class
│ └── META-INF
│ └── MANIFEST.MF
└── src
├── com
│ └── company
│ ├── CheckFile.txt
│ └── Main.java
└── META-INF
└── MANIFEST.MF
示例 java 代码:
public static void GetResource() {
String result = null;
String url = (Main.class.getResource("CheckFile.txt")).getPath();
System.out.println("URL = " + url);
try {
Scanner reader = new Scanner(new File(url));
while (reader.hasNextLine()) {
String data = reader.nextLine();
result = data;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
System.out.println(result);
}
输出错误:
$ java -jar ClassFileTry.jar
URL = file:/home/tucna/Desktop/ClassFileTry/out/artifacts/ClassFileTry_jar/ClassFileTry.jar!/com/company/CheckFile.txt
java.io.FileNotFoundException: file:/home/tucna/Desktop/ClassFileTry/out/artifacts/ClassFileTry_jar/ClassFileTry.jar!/com/company/CheckFile.txt (No such file or directory.)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:211)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:153)
at java.base/java.util.Scanner.<init>(Scanner.java:639)
at com.company.Main.GetResource(Main.java:49)
at com.company.Main.main(Main.java:18)
null
我正在使用 Linux 和 IntelliJ java 15.0.2
所以我的问题是:我做错了什么以及如何解决?为什么 getResourceAsStream()
读取文件有效而 getResource()
无效?
如果有任何帮助,我将非常感激! 提前致谢!
您可以以流的形式阅读您的资源。试试这个:
StringBuilder builder = new StringBuilder();
try (InputStream is = Main.class.getResourceAsStream("/CheckFile.txt")) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line;
while((line = reader.readLine()) != null) {
if (builder.length() > 0) {
builder.append("\n");
}
builder.append(line);
}
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, "", ex);
throw new UncheckedIOException(ex);
}
System.out.println(builder.toString());
java.io.File
表示磁盘上的实际文件。您的资源不是;它是 jar 文件中的一个条目。 new File(someUrl)
是一个非首发。首选的替代方案是永远不要将文件用于这些东西,而是检查您正在使用的 API,它往往有一个采用 URL
或 InputStream
的替代形式。所以就在这里,Scanner can also take an InputStream:
try (InputStream in = Main.class.getResourceAsStream("/CheckFile.txt")) {
Scanner s = new Scanner(in, StandardCharsets.UTF_8);
// do you magic here.
} catch (IOException e) {
throw new UncheckedIOException(e);
}
昨天我终于完成了我的 JavaFX 应用程序,它在 IDE 中完美地 运行,但是当我试图将它转换为 .jar
文件然后 运行 时。 .. 它没有用。我发现我的 class 无法使用 getClass().getResource()
导入任何 .fxml
文件。
所以我创建了一个示例代码,它试图读取文本文件 CheckFile.txt
。
Class路径树:
.
├── ClassFileTry.iml
├── out
│ ├── artifacts
│ │ └── ClassFileTry_jar
│ │ └── ClassFileTry.jar
│ └── production
│ └── ClassFileTry
│ ├── com
│ │ └── company
│ │ ├── CheckFile.txt
│ │ └── Main.class
│ └── META-INF
│ └── MANIFEST.MF
└── src
├── com
│ └── company
│ ├── CheckFile.txt
│ └── Main.java
└── META-INF
└── MANIFEST.MF
示例 java 代码:
public static void GetResource() {
String result = null;
String url = (Main.class.getResource("CheckFile.txt")).getPath();
System.out.println("URL = " + url);
try {
Scanner reader = new Scanner(new File(url));
while (reader.hasNextLine()) {
String data = reader.nextLine();
result = data;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
System.out.println(result);
}
输出错误:
$ java -jar ClassFileTry.jar
URL = file:/home/tucna/Desktop/ClassFileTry/out/artifacts/ClassFileTry_jar/ClassFileTry.jar!/com/company/CheckFile.txt
java.io.FileNotFoundException: file:/home/tucna/Desktop/ClassFileTry/out/artifacts/ClassFileTry_jar/ClassFileTry.jar!/com/company/CheckFile.txt (No such file or directory.)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:211)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:153)
at java.base/java.util.Scanner.<init>(Scanner.java:639)
at com.company.Main.GetResource(Main.java:49)
at com.company.Main.main(Main.java:18)
null
我正在使用 Linux 和 IntelliJ java 15.0.2
所以我的问题是:我做错了什么以及如何解决?为什么 getResourceAsStream()
读取文件有效而 getResource()
无效?
如果有任何帮助,我将非常感激! 提前致谢!
您可以以流的形式阅读您的资源。试试这个:
StringBuilder builder = new StringBuilder();
try (InputStream is = Main.class.getResourceAsStream("/CheckFile.txt")) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line;
while((line = reader.readLine()) != null) {
if (builder.length() > 0) {
builder.append("\n");
}
builder.append(line);
}
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, "", ex);
throw new UncheckedIOException(ex);
}
System.out.println(builder.toString());
java.io.File
表示磁盘上的实际文件。您的资源不是;它是 jar 文件中的一个条目。 new File(someUrl)
是一个非首发。首选的替代方案是永远不要将文件用于这些东西,而是检查您正在使用的 API,它往往有一个采用 URL
或 InputStream
的替代形式。所以就在这里,Scanner can also take an InputStream:
try (InputStream in = Main.class.getResourceAsStream("/CheckFile.txt")) {
Scanner s = new Scanner(in, StandardCharsets.UTF_8);
// do you magic here.
} catch (IOException e) {
throw new UncheckedIOException(e);
}