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

186

我正在尝试获取资源的路径,但是一直没有成功。

这种方式可以工作(在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 (无此文件或目录)

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


1
因此,该类只接收一个文件路径(配置文件)。 - noripcord
3
你可能应该让那个类处理一个输入流,你可以从任意来源获取输入流。 - Carl Manaster
1
是的,我知道。但用另一种方式会更清晰、更简洁。不过还是谢谢你。 - noripcord
1
你是在尝试做类似于这个问题中的选项#4吗?https://dev59.com/j3RA5IYBdhLWcg3w8SiJ#775565 - erickson
1
嗯,我遇到了相同的问题。我想要能够将一个图像捆绑在JAR中,然后在运行时使用HTML在JTextPanel中使用该图像。HTML需要相对路径(并设置文档基础为适当的内容)或绝对路径。您可以获取JAR文件中的文件路径吗? - twolfe18
显示剩余3条评论
17个回答

1

可能有点晚了,但是你可以使用我的库KResourceLoader从你的jar包中获取资源:

File resource = getResource("file.txt")

1
以下路径对我有效:classpath:/path/to/resource/in/jar


2
@Anatoly,您能否分享更多关于上述内容的细节? - Kasun Siyambalapitiya

1
private static final String FILE_LOCATION = "com/input/file/somefile.txt";

//Method Body


InputStream invalidCharacterInputStream = URLClassLoader.getSystemResourceAsStream(FILE_LOCATION);

getSystemResourceAsStream获取这个是最好的选择。通过获取输入流而不是文件或URL,可以在JAR文件和独立运行时工作。

0
这个类函数可以通过相对文件路径在.jar文件中获取绝对文件路径。

public class Utility {

    public static void main(String[] args) throws Exception {
        Utility utility = new Utility();
        String absolutePath = utility.getAbsolutePath("./absolute/path/to/file");
    }

    public String getAbsolutePath(String relativeFilePath) throws IOException {
        URL url = this.getClass().getResource(relativeFilePath);
        return url.getPath();
    }
}


如果目标文件与Utility.java在同一目录中,则您的输入将为./file.txt
当您在getAbsolutePath()中仅输入/时,它会返回/Users/user/PROJECT_NAME/target/classes/。这意味着您可以像这样选择文件/com/example/file.txt

0

在你的jar的资源文件夹(java/main/resources)中添加文件(假设你已经添加了一个名为imports.xml的xml文件),之后,如果你使用Spring,就像下面这样注入ResourceLoader

@Autowired
private ResourceLoader resourceLoader;

在 tour 函数内,编写以下代码以加载文件:
    Resource resource = resourceLoader.getResource("classpath:imports.xml");
    try{
        File file;
        file = resource.getFile();//will load the file
...
    }catch(IOException e){e.printStackTrace();}

0

当资源在jar文件中时,该资源的位置绝对位于包层次结构中(而不是文件系统层次结构中)。因此,如果您有一个名为com.example.Sweet的类加载名为./default.conf的资源,则该资源的名称指定为/com/example/default.conf

但如果它在jar中,则不是文件...


0

或许这个方法可以用于快速解决问题。

public class TestUtility
{ 
    public static File getInternalResource(String relativePath)
    {
        File resourceFile = null;
        URL location = TestUtility.class.getProtectionDomain().getCodeSource().getLocation();
        String codeLocation = location.toString();
        try{
            if (codeLocation.endsWith(".jar"){
                //Call from jar
                Path path = Paths.get(location.toURI()).resolve("../classes/" + relativePath).normalize();
                resourceFile = path.toFile();
            }else{
                //Call from IDE
                resourceFile = new File(TestUtility.class.getClassLoader().getResource(relativePath).getPath());
            }
        }catch(URISyntaxException ex){
            ex.printStackTrace();
        }
        return resourceFile;
    }
}

你是否省略了一些上下文?这个错误信息是:java.lang.NullPointerException: Attempt to invoke virtual method 'java.security.CodeSource java.security.ProtectionDomain.getCodeSource()' on a null object reference - Allen Luce
我编辑了答案,并写下了我在软件中使用的整个方法。 - gbii

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接