我有类似以下项目结构的东西
-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);
答案 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_package_name是此对象的包名称,其中'/'替换为'。' ( '\ u002e')。
至于为什么这可以在Eclipse上运行,而不是从命令行运行,我仍然不确定,但请看下面的@ andy的评论。
这article给出的是对这种情况的一个很好的解释。