首先,源码可以帮助理解。
先说getResourceAsStream(String path),作用将加载到的文件(包括编译后的.class文件和普通文件)转换为inputstream流。总结以下四种用法:(以Person类为例)
第一种:Person.class.getResourceAsStream(String path)
path可以加上"/",加上的话,表示从classpath(是JVM用到的一个环境变量,它用来指示JVM如何搜索class)下加载,即bin目录下;不加的话表示从当前目录下加载。源码可以看看:
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); //这个方法调用的就是下面的getResourceAsStream(String name)
}
第二种:Person.class.getClassLoader().getResourceAsStream(String path)
path不用加"/",源码中有这样信息:
public InputStream getResourceAsStream(String name) {
URL url = getResource(name);
try {
return url != null ? url.openStream() : null;
} catch (IOException e) {
return null;
}
}
第三种推荐使用:Thread.currentThread().getContextClassLoader().getResourceAsStream(String path)
多线程中用它合适,因为他是获取的是当前线程的类加载器
第四种:ServletContext. getResourceAsStream(String path),ServletContext对象用于web项目
获取webRoot/webContent目录下的资源文件,这里指的是tomcat服务器中部署的项目webRoot/webContent目录下的资源文件,而不是eclipse工作空间下的。加不加"/"都可以,但WEB-INF下的文件(如classes中的.class)获取不到。
再说getResource(String parh),作用是获取资源路径(资源指编译后的.class文件和普通文件),返回URL对象。以下摘自这里。以后再来总结。。。。
1.FileTest.class.getResource("")
得到的是当前类FileTest.class文件的URI目录。不包括自己!
如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/com/test/
2.FileTest.class.getResource("/")
得到的是当前的classpath的绝对URI路径。
如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/
3.Thread.currentThread().getContextClassLoader().getResource("")
得到的也是当前ClassPath的绝对URI路径。
如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/
4.FileTest.class.getClassLoader().getResource("")
得到的也是当前ClassPath的绝对URI路径。
如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/
5.ClassLoader.getSystemResource("")
得到的也是当前ClassPath的绝对URI路径。
如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/
我推荐使用Thread.currentThread().getContextClassLoader().getResource("")来得到当前的classpath的绝对路径的URI表示法。
最后先总结下吧,大致了解了下源码,得到以下信息:(getResource,目前先做如下总结)
FileTest.class.getResource()会获得一个类加载器 ClassLoader cl = getClassLoader0();判断cl是否为空,若为空则将系统默认的类加载器给了他,然后调用getResource()。而FileTest.class.getClassLoader().getResource(""),直接调用了getResource()方法。
Person.class.getResourceAsStream()和Person.class.getClassLoader().getResourceAsStream()与上述类似。总的来说都是需要先获得类加载器,用类加载器才能获取资源路径或者进行下一步处理,即将资源文件转换为io流对象。
getResourceAsStream方法中io流的获取代码:
public InputStream getResourceAsStream(String name) {
URL url = getResource(name);
try {
return url != null ? url.openStream() : null;
} catch (IOException e) {
return null;
}
}
url.openStream()就是打开了流嘛。