即使我使用了 getResourceAsStream,我也无法在 JAR 中加载资源

问题描述 投票:0回答:1

我想从 JavaFX 应用程序中的 JAR 加载图像,但即使它按预期在我的 IDE 中工作,它们也不会显示。这是我从加载函数

file:/C:/Users/anass/OneDrive/Desktop/anass_coder/target/classes/com/anass/anass_code_editor/assets/languages/
获得的输出,这是图像文件夹的绝对路径
C:\Users\anass\OneDrive\Desktop\anass_coder\src\main\resources\com\anass\anass_code_editor\assets\languages

这是加载函数:

public static void loadIconImages() {
    iconImages = new HashMap<>();
    URL imagesDirURL = App.class.getResource("/com/anass/anass_code_editor/assets/languages");
    if (imagesDirURL != null) {
        System.out.println(imagesDirURL.toExternalForm());
        try {
            InputStream imagesDirStream = imagesDirURL.openStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(imagesDirStream));
            String line;
            while ((line = reader.readLine()) != null) {
                String name = line.trim().toLowerCase();
                if (name.contains(".")) {
                    String resourcePath = "/com/anass/anass_code_editor/assets/languages/" + name;
                    InputStream imageStream = App.class.getResourceAsStream(resourcePath);

                    if (imageStream != null) {
                        iconImages.put(name.substring(0, name.indexOf(".")), new Image(imageStream));
                        imageStream.close();
                    }
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    } else {
        System.out.println("No dir");
    }
}

我正在使用 Maven 来捆绑桌面应用程序。

我尝试过

getResourceAsStream
。 URI 没有层次结构。错误消失了,但找不到资源。资源被很好地捆绑并存在于 JAR 存档中。

java jar desktop-application executable-jar javafx-11
1个回答
4
投票

您要求提供目录名称作为资源。这是不受支持的并且通常不起作用。它应该“永远不会”工作,但规范也不承诺“不起作用”。重点是,不要——它并不(总是)有效,因此毫无用处。然后,您尝试将此目录作为文件(作为字节流)读取,希望它能以某种方式生成文件名列表。那也行不通。或者更确切地说,它不应该 - 没有规范声称这是必须发生的事情,因此 JVM 可以自由地不这样做。 简单的结论是,资源加载的概念

不支持任何

list任何命令

。这段代码
想要加载“文件夹中的每个资源”,这是一个列表操作,因此如果没有黑客攻击就无法编写 此问题的常见解决方案涉及创建一个包含每个文件的文件(该文件是已知名称,因此无需可用的

list

原语即可读取)。然后,您可以打开“包含列表的资源”,然后使用

that
列表 - 现在您不再依赖加载器系统为您列出(这很好,因为这不是它实际上可以做的事情)。 当然,维护“包含图像资源列表的文件”是一件痛苦的事情。所以,我们解决了这个问题,但这个修复引入了一个新问题。解决“那个”问题的一种方法是在构建过程中自动生成包含所有图像名称的文件。注释处理器可以做到这一点,因此可以构建插件。但是,现在,首先要做的事情是:手动写出所有图像的列表,将其粘贴在已知位置,使用

.getResourcesAsStream

读取 that 文件,然后使用 that 循环并加载每个图像。

一旦有效,您可能想问一个单独的问题,显示该代码并解释其按原样工作,但您正在寻找一种方法来在构建过程中自动生成“包含每个图像文件名称的文件”。 
    

© www.soinside.com 2019 - 2024. All rights reserved.