标签:
1、使用类的Class来加载文件,比如:MyTest.class.getResource("myfile.txt"):
第一种:如果getResource的参数没有以“/”开头,则会从MyTest这个类的package下查找myfile.txt。比如如果MyTest的全名是:com.test.MyTest,则会从com.test这个路径下找这个文件。
第二种:如果getResource的参数以“/”开头,则会从MyTest这个类的类加载器根目录下加载这个文件,比如WEB-INF/classes这个目录下和WEB-INF/lib的jar包的根目录下。
第三种:其实是第一种的延伸,如果参数为空,如:MyTest.class.getResource("");则会返回MyTest.class这个类所在的目录,如:file:/D:/workspace/demo/com/test/;
第四种:其实是第二种的延伸,如果参数为"/",如:MyTest.class.getResource("/");则会返回MyTest.class这个类所在工程classpath的路径,如:file:/D:/workspace/demo/
2、使用类的类加载器来加载文件,比如:
第一种:
ClassLoader loader = MyTest.class.getClassLoader();
URL fileUrl = loader.getResource("com/test/myfile.txt");
这种方式是直接从类加载器的根目录开始计算路径的,比如WEB-INF/classes这个目录和WEB-INF/lib的jar包的根目录开始计算。而且注意“类加载器的双亲委托原则”,会让其父加载器先加载,然后才是自己找。
第二种:如果第一种中传入getResource的参数是"",则返回的是系统classpath的根目录,这里是:file:/D:/workspace/demo/
第三种:如果第一种中传入getResource的参数是"/",则返回的是null
3、以上两种方法与之相对应都有一个getResourceAsStream,这个只不过返回的不是一个URL,而是一个InputStream而已,比如方法如下:
InputStream inputStream = MyTest.class.getResourceAsStream("myfile.txt"):
4、注意:以上的两种方式返回的都是一个URL,也就是说只要找到第一个文件就会直接返回,而不会再往下找。那么如果WEB-INF/lib下的每个jar包里的相同路径下都有一个文件,比如每个jar包下都有一个redeme.txt,那如果想要全部加载上来,该怎么办呢?则可以使用类加载器的getResources这个函数。这个方法要找遍所有祖先类加载器和自己的类加载器路径下的所有同名(路径也相同)文件比如:
ClassLoader loader = MyTest.class.getClassLoader();
try {
Enumeration<URL>
urls = loader.getResources("com/yc/demo/myfile.txt");
} catch (IOException e) {
e.printStackTrace();
}
如果我们在我们应用的src下放一个readme.txt,在WEB-INF/lib的其中两个jar包的根目录下都放一个readme.txt文件,则会得到3个元素的URL数组。
file:/D:/workspace/demo/WEB-INF/classes/readme.txt
jar:file:/D:/workspace/demo/WEB-INF/lib/a.jar!/readme.txt
jar:file:/D:/workspace/demo/WEB-INF/lib/b.jar!/readme.txt
注意:我曾经思考为啥类的Class为啥没有getResources这个方法,而只有getResource这个方法呢?我思考这大约是因为以类所在的位置作为基准的同目录下的文件是不能重复的,所以没有必要有getResources这个方法。比如在MyTest.class这个类所在的目录下当然不能有两个readme.txt这个文件。
这个还没有完,还有很多知识点没有搞清楚,先写到这里,随后再补上。
标签:
原文地址:http://blog.csdn.net/achilles12345/article/details/45010757