通过Java的getResourceAsStream
获取资源主要有以下两种方式:
Class.getClassLoader.getResourceAsStream(String name)
: 默认是从ClassPath
下获取资源,name
不能以/
开头,代表ClassPath
下的相对路径。Class.getResourceAsStream(String name)
:name
不以/
开头时默认是从此类所在的包下取资源,以/
开头则是从ClassPath
下获取。
假设此时在resources
目录下有一个file/hello.txt
文件,则可通过以下代码来进行获取:
public class App {
public static void main(String[] args) {
//通过ClassLoader方式获取不以"/"开头
InputStream input1 = App.class.getClassLoader().getResourceAsStream("file/hello.txt");
//通过Class方式则必须以"/"开头
InputStream input2 = App.class.getResourceAsStream("/file/hello.txt")
}
}
Class.getClassLoader.getResourceAsStream
Class.getClassLoader.getResourceAsStream(String name)
中的name
相当于ClassPath
下的相对目录,查找时会用ClassPath
下的目录加上name
来构造资源的URL
。
使用maven
工具打包时,src
目录下的代码以及resources
目录下的资源默认会打包到target/classes
目录下,ClassPath
配置时一般会配置.
(表示当前目录),即会从当前目录下查找类。
结合以上两点,向Class.getClassLoader.getResourceAsStream
方法传入file/hello.txt
可以获取到target/classes/file
下的hello.txt
文件。
Class.getResourceAsStream
Class.getResourceAsStream(String name)
中的name
若不以/
开头,则会从当前类所在的包下获取资源,假设App
类的包名为org.example
,则解析后的路径为org/example/file/hello.txt
,该值会作为Class.getClassLoader.getResourceAsStream(String name)
中的参数传入,但默认情况下maven
并不会将org.example
包下的资源文件打包到target/classes
下,因此获取不到对应资源。
Class.getResourceAsStream(String name)
的源码如下:
public InputStream getResourceAsStream(String name) {
name = resolveName(name);
ClassLoader cl = getClassLoader0();
if (cl==null) {
// A system class.
return ClassLoader.getSystemResourceAsStream(name);
}
return cl.getResourceAsStream(name);
}