如何获取 Java JAR 文件中资源的路径

2022-08-31 06:37:41

我试图找到一条通往资源的路径,但我没有运气。

这有效(在IDE和JAR中),但这样我就无法获取文件的路径,只能获取文件内容:

ClassLoader classLoader = getClass().getClassLoader();
PrintInputStream(classLoader.getResourceAsStream("config/netclient.p"));

如果我这样做:

ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("config/netclient.p").getFile());

结果是:java.io.FileNotFoundException: file:/path/to/jarfile/bot.jar!/config/netclient.p (No such file or directory)

有没有办法获取资源文件的路径?


答案 1

这是故意的。“文件”的内容可能无法作为文件提供。请记住,您正在处理的类和资源可能是 JAR 文件或其他类型的资源的一部分。类装入器不必为资源提供文件句柄,例如,jar 文件可能尚未扩展到文件系统中的单个文件中。

通过获取java.io.File可以执行的任何操作都可以通过将流复制到临时文件中并执行相同的操作来完成,如果java.io.File是绝对必要的。


答案 2

加载资源时,请确保注意到以下两者之间的区别:

getClass().getClassLoader().getResource("com/myorg/foo.jpg") //relative path

getClass().getResource("/com/myorg/foo.jpg")); //note the slash at the beginning

我猜,这种混淆在加载资源时会导致大多数问题。


此外,当您加载图像时,它更易于使用:getResourceAsStream()

BufferedImage image = ImageIO.read(getClass().getResourceAsStream("/com/myorg/foo.jpg"));

当您确实必须从JAR归档文件加载(非映像)文件时,您可以尝试以下操作:

File file = null;
String resource = "/com/myorg/foo.xml";
URL res = getClass().getResource(resource);
if (res.getProtocol().equals("jar")) {
    try {
        InputStream input = getClass().getResourceAsStream(resource);
        file = File.createTempFile("tempfile", ".tmp");
        OutputStream out = new FileOutputStream(file);
        int read;
        byte[] bytes = new byte[1024];

        while ((read = input.read(bytes)) != -1) {
            out.write(bytes, 0, read);
        }
        out.close();
        file.deleteOnExit();
    } catch (IOException ex) {
        Exceptions.printStackTrace(ex);
    }
} else {
    //this will probably work in your IDE, but not from a JAR
    file = new File(res.getFile());
}

if (file != null && !file.exists()) {
    throw new RuntimeException("Error: File " + file + " not found!");
}

推荐