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
.
我正在编写一个涉及图形界面的程序,我在下面的代码中使用 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
.