在 jar 文件中如何输出随机图像?

How can I output a random image when in a jar file?

下面的代码在我的编辑器 运行 时有效,但是当使用 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;
    }

有人可以建议我如何修改我的代码或编辑器以在编译时加载文件。

我已经阅读了其他访问文件的方法,但由于我需要从文件夹中随机 select,因此我需要使用 File class.

问题是您正在尝试以文件形式访问 URL 资源。

this就可以得到所有的图片,然后可以这样做:

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;

没有在运行时列出资源的安全方法。

(有些人可能建议的方法有时有效,但不会一直有效。Class.getResource 不保证提供列表;ProtectionDomain.getCodeSource 可以 return null。)

但你不需要。这是你的申请;您已经知道放入了哪些文件。

最好的方法是 hard-code 文件列表,或者包含一个包含文件列表的简单文本文件。

例如,假设您创建(或生成)了一个名为 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() 方法不是 return 有效的文件名。 它只有 return 是 URL 的路径部分。在 URL 中有许多字符是非法的,因此路径部分 percent-escapes 它们。如果您忽略这个事实,由 getFile() 编辑的值 return 最终将失败。

(误导方法名称的原因是 URL class 是 Java 1.0 的一部分,并且在 1990 年代中期,所有 URLs实际上指的是物理文件。)

I need to use the File class

每个 .jar 条目只是单个 .jar 文件中压缩字节的子序列,因此您将永远无法使用文件读取这样的条目。 Class.getResource and Class.getResourceAsStream 是阅读这些条目的唯一正确方法。