类getResourceAsStream()资源在不同的包中

时间:2013-05-01 14:36:49

标签: java eclipse classloader

我有类似以下项目结构的东西

-project 
    -src/main/java // source folder
        -com.mypackage
            -Utility.java
            -some.properties
    -src/main/resources // source folder
        -configuration_files
            -configuration_report.txt

我正在使用Eclipse的jar函数生成Export。以上转换为jar结构:

-myjar.jar
    -com
        -mypackage
            -Utility.class
            -some.properties
    -configuration_files
        -configuration_report.txt

Utility课程中,我正试图从InputStream获取configuration_report.txt

我这样做(它在static方法内):

Utility.class.getResourceAsStream("/configuration_files/configuration_report.txt"); 

似乎是由this question的答案验证的,因为该文件与请求它的类不在同一个包中。

然而,当我运行它时,它返回null。为什么呢?

请注意,对于some.properties文件,我可以同时执行这两项操作

Utility.class.getResourceAsStream("/com/package/some.properties");
Utility.class.getResourceAsStream("some.properties");

我会得到这个流。

如果它有任何区别,我会从命令行运行它。

java [-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=1044] -cp myjar.jar MyMain

如果我尝试在Eclipse中运行它,它可以工作......

修改

此代码相关。无论有没有前面的/,它都会返回null

    String sourceFilePath = "/configuration_files" + File.separator + "configuration_report.txt";
    InputStream in = Utility.class.getResourceAsStream(sourceFilePath);

1 个答案:

答案 0 :(得分:7)

经过多次尝试,解决方案归结为ClassLoader#getResource(String)的这个小javadoc条目:

  

资源的名称是'/' - 标识资源的分隔路径名。

我最初发布的代码片段已经完成了

Utility.class.getResourceAsStream("/configuration_files/configuration_report.txt"); 

但我没有使用/,我在编辑中使用了File.separator

String sourceFilePath = "/configuration_files" + File.separator + "configuration_report.txt";

认为类加载器像操作系统特定的文件操作一样工作。第一个/已匹配,但File.separator评估为\\,因为我在Windows上。

Class#getResource(String)的javadoc说的更多相同。

  

其中modified_pa​​ckage_name是此对象的包名称,其中'/'替换为'。' ( '\ u002e')。

至于为什么这可以在Eclipse上运行,而不是从命令行运行,我仍然不确定,但请看下面的@ andy的评论。

article给出的是对这种情况的一个很好的解释。