以下代码在编辑器中运行时有效,但在使用eclipse编译到可运行的jar文件中时,无法加载图像。
public static BufferedImage getRandomImage() {
// returns a random image from the Images folder
Random rand = new Random();
URL res = Card.class.getResource("Images"); // located in /src/.../Images
File f = new File(res.getFile());
if (!f.exists()) {
return new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
}
File[] files = f.listFiles();
int random = rand.nextInt(files.length);
BufferedImage img = null;
try {
img = ImageIO.read(files[random]);
} catch (IOException e) {
e.printStackTrace();
}
return img;
}
有人能建议我如何修改我的代码或编辑器以在编译时加载文件吗。
我读过其他访问文件的方法,但由于我需要从文件夹中随机选择,所以我需要使用File
类。
在运行时没有安全的方法列出资源。
(有些人可能会建议一些有时有效,但不会一直有效的方法。Class.getResource不能保证提供列表;ProtectionDomain.getCodeSource可以返回null。(
但你不需要。这是你的申请;你已经知道你把什么文件放进去了。
最好的方法是对文件列表进行硬编码,或者包含一个包含文件列表的简单文本文件。
例如,假设您创建(或生成(了一个名为image-files.txt的文件,其中每一行都包含图像文件的基本名称,并将该文件嵌入到您的应用程序中:
List<String> imageNames;
try (BufferedReader linesReader = new BufferedReader(
new InputStreamReader(
Card.class.getResourceAsStream("image-files.txt"),
StandardCharsets.UTF_8));
Stream<String> lines = linesReader.lines()) {
imageNames = lines.collect(Collectors.toList());
} catch (IOException e) {
throw new UncheckedIOException(e);
}
int random = rand.nextInt(imageNames.length());
String imageName = imageNames.get(random)));
BufferedImage img;
try {
img = ImageIO.read(Card.class.getResource(imageName));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
return img;
注意:URL的getFile((方法不会返回有效的文件名它只返回URL的路径部分。URL中有许多字符是非法的,因此路径部分百分比会转义这些字符。如果忽略这个事实,getFile((返回的值最终会失败
(产生误导性方法名称的原因是URL类是Java 1.0的一部分,在20世纪90年代中期,所有URL实际上都引用了物理文件。(
我需要使用
File
类
每个.jar条目只是单个.jar文件中压缩字节的子序列,因此您将永远无法使用file读取此类条目。Class.getResource和Class.getResourceAsStream是读取这些条目的唯一正确方法。
问题是您试图以文件的形式访问资源的URL。
有了这个,你可以获得所有的图像,然后你可以这样做:
List<String> arr = getResourceFiles("Images");
String imgPath = arr.get(rand.nextInt(arr.size()));
InputStream stream = Card.class.getResourceAsStream("Images/" + imgPath);
try {
img = ImageIO.read(stream);
} catch (IOException e) {
e.printStackTrace();
}
return img;