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,它往往有一个采用 URLInputStream 的替代形式。所以就在这里,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);
}