要区分Class的getResourceAsStream和ClassLoader的getResourceAsStream方法。
ClassLoader的该方法如果name以/开头那么就什么也找不到了。
Class的getResourceAsStream方法
1、如果name以/开头那么就把/以后的name传递给ClassLoader的 getResourceAsStream方法。
2、如果不已/开头那么将该class的包名加上name作为参数(用/代替.)之后 传给ClassLoader的对应方法。[code=java]package cn.itcast.heima;
import java.io.*;
......
InputStream in = test.getClass().getResourceAsStream( "heima.txt ");
InputStream in = test.getClass().getResourceAsStream( "/cn/itcast/heima/heima.txt ");
InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream( "cn/itcast/heima/heima.txt ");
....... [/code]从上可以看出前一个只是引用了后一个的方法。不过其中加了一些判断。
我们可以看下源代码就了解到:[code=java] // java.lang.Class
public InputStream getResourceAsStream(String name) {
name = resolveName(name);
ClassLoader cl = getClassLoader0();
if (cl==null) { // 如果找不到ClassLoader,就寻找系统资源
// A system class.
return ClassLoader.getSystemResourceAsStream(name);
}
return cl.getResourceAsStream(name); // 否则就调用ClassLoader对应方法
}
//...
/**
* Add a package name prefix if the name is not absolute Remove leading "/"
* if name is absolute
*/
private String resolveName(String name) {
if (name == null) {
return name;
}
if (!name.startsWith("/")) {
Class c = this;
while (c.isArray()) {
c = c.getComponentType();
}
String baseName = c.getName();
int index = baseName.lastIndexOf('.');
if (index != -1) {
name = baseName.substring(0, index).replace('.', '/')
+"/"+name;
}
} else {
name = name.substring(1);
}
return name;
}[/code]两个方法的区别是资源的定义不同:
一个主要用于相对与一个object取资源,而另一个用于取相对于classpath的资源,用的是绝对路径。
由此可见,如果使用Class.getResourceAsStream(String)方法,则资源名要么设置为类所在包的相对名,要么设置为全路径名,而如果使用ClassLoader的相应方法,则要设置为不带根的全路径名。也就是楼主所说的不加"/"
[ 本帖最后由 詹季春 于 2011-07-30 19:12 编辑 ] |