从 jar 文件中获取资源

Get resources from a jar file

我希望我的 jar 文件能够从自身访问一些文件。我知道如何为 BufferedImage 执行此操作,但这不适用于其他文件。我只想从我的罐子里提取一些拉链。我在 eclipse 中创建了一个 class 文件夹,将 zips 放入其中并使用

    public File getResFile(String name){

    return new File(getClass().getResource(name).getFile());


}

获取 File 实例并提取它。它在 eclipse 中工作正常,但是一旦我将它导出到一个 jar,它就会说

Exception in thread "main" java.io.FileNotFoundException: file:\C:\Users\DeLL\Desktop\BoxcraftClient\ClientInstaller.jar!\client.bxc (The filename, directory name, or volume label syntax is incorrect)
    at java.util.zip.ZipFile.open(Native Method)
    at java.util.zip.ZipFile.<init>(ZipFile.java:220)
    at java.util.zip.ZipFile.<init>(ZipFile.java:150)
    at java.util.zip.ZipFile.<init>(ZipFile.java:164)
    at Launcher.install(Launcher.java:43)
    at Launcher.main(Launcher.java:33)

我已经花了大约 6 个小时来解决这个问题,但找不到解决方案。请帮忙!

getResource()returns是URL而不是File是有原因的,因为资源可能不是[=22] =] 一个文件,并且由于您的代码打包在 Jar 文件中,因此它不是一个文件而是一个 zip 条目。

读取资源内容的唯一安全方法是作为 InputStream,通过调用 getResourceAsStream() 或在返回的 URL 上调用 openStream() .

使用这些方法之一,来自 class Class - getResource(java.lang.String) - getResourceAsStream(java.lang.String)

    this.getClass().getResource(name);
    this.getClass().getResourceAsStream(name);

警告: 默认情况下,它从包中找到 this.class 的位置加载文件。因此,如果从 class org.organisation.project.App 中使用它,则该文件需要位于目录 org/organisation/project 中的 jar 中。如果文件位于 jar 内的根目录或其他目录中,请使用文件名的 /。喜欢 /data/names.json.

首先使用 java System.out.println("classpath is: " + System.getProperty("java.class.path")); 检查您的 class 路径以查看 class 路径是否有您的 jar 文件。

然后使用getclass().classloader.getResourceAsStream(name)。查看返回的 URL 是否正确。在 URL 上调用方法 isFile() 以检查 URL 是否实际上是一个文件。然后调用getFile()方法。

使用Spring的PathMatchingResourcePatternResolver

它可以解决从 IDE 或文件系统启动程序包的问题:

public List<String> getAllClassesInRunningJar() throws Exception {
    try {
        List<String> list = new ArrayList<String>();

        // Get all the classes inside the package com.my.package:
        // This will do the work for both launching the package from an IDE or from the file system:  
        String scannedPackage = "com.my.package.*";

        // This is spring - org.springframework.core; use these imports:
        //  import org.springframework.core.io.Resource;
        //  import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
        PathMatchingResourcePatternResolver scanner = new PathMatchingResourcePatternResolver();
        Resource[] resources = scanner.getResources(scannedPackage.replace(".", "/"));

        for (Resource resource : resources)
            list.add(resource.getURI().toString());
        return list ;
    } catch (Exception e) {
        throw new Exception("Failed to get the classes: " + e.getMessage(), e);
    }
}