ImageIO 找不到文件

ImageIO Cannot Find File

我正在编写一个涉及图形界面的程序,我在下面的代码中使用 ImageIO 将图像读入 BufferedImage(变量 starImg):

public Star() {
    super();
    if (starImg == null) {
        try {
            starImg = ImageIO.read(new File("star.png"));
        } catch (IOException e) {
            System.out.println("There was an issue reading the file: " + e);
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

除了代码总是最终输出未找到 IO 文件异常消息,即使它不应该。我的 star.png 文件与我的代码位于同一文件夹中(运行 使用 Eclipse),我确保它是 png 而不是 jpg,并尝试了其他操作,例如将 File 更改为 FileInputStream,所以我似乎无法弄清楚为什么无法读取此图像。也许这与我正在使用 Eclipse 这一事实有关,尽管我发现这不太可能。我查看了与同一问题相关的其他答案,但解决他们问题的解决方案并没有解决我的问题。

如果有人能指出我代码中的错误,将不胜感激。

My star.png file is in the same folder as my code (ran using Eclipse)

好吧,那是你的问题。

new File("star.png") 将在进程当前工作目录中查找。

那是哪里? 谁知道呢! - 这取决于用户;应用程序从哪里开始。因此,这被打破了一个概念:绝对不能保证它是正确的地方。

情况变得更糟 - java 应用程序以 jar 或 jmod 的形式提供,并且它们需要的文件包含在其中。 jar 文件或 jmod 文件中的条目 不是文件 new File() 不可能阅读这些

结论是这个过程(制作一个文件对象,传递给ImageIO.read)不能资源

解决方案是要求 java 类加载系统从虚拟机加载 类 的任何地方为您提供资源。如果那是来自磁盘,很好,从那里获取 em。如果它来自 jar 或 jmod 文件,太好了,从那里获取 em。

这就是你的做法:

URL url = Star.class.getResource("star.png");

// - OR -

try (InputStream in = Star.class.getResourceAsStream("star.png")) {
   // use in here
}

当你有一个接受 URL 对象的 API 时,第一个很有用。我很确定 ImageIO.read() 就是这样一个 API.

第二个对于接受 InputStreams 的 APIs 很有用。 ImageIO.read 也这样做 - 如果两者都可用,则基于 URL 的更简单(在这种情况下不需要 try-with-resources)。

请注意,这将在同一个地方 Star.class 结束,可以这么说,在 Star 的 'package' 中。如果您更愿意从 'root' 文件夹(例如 jar 的根目录)开始,请使用例如"/img/star.png" 相反;这将在名为 'img' 的目录中查找该文件,并且该目录必须在 'root' 中。所以,如果 Star 在顶部有 package com.foo;,则有一些构造(jar 文件、jmod 等)有一个 com 目录,它有一个 foo 目录,它有一个 Star.class 文件。对于 "/img/star.png",必须有一个名为 img 的目录,作为名为 com.

的目录的同级目录

Eclipse 会自动将 src 文件夹中的非 java 文件复制过来,打个比方:它通过编译 'copies' java 文件,它 'compiles'非 java 文件,只需将它们复制过来。因此,这在 eclipse 中工作正常,并且在构建系统中也工作正常(请注意,对于 maven,有一个目录结构要遵守。来源进入 src/main/java,非 java 的东西进入 src/main/resources.