http://www.javaworld.com/article/2077352/java-se/smartly-load-your-properties.html
http://stackoverflow.com/questions/676250/different-ways-of-loading-a-file-as-an-inputstream
使用FileInputStream, FileReader, and RandomAccessFile等文件方式进行定位资源时,总会出现各种问题(例如发布后等等)。一种好的方式是使用classloader来定位资源,它是资源名和实际资源位置之间一层抽象。
当想取得Classpath下的资源时,有几种方式:
- this.getClass().getResource()
- ResourceBundle.getBundle ();
- this.getClass().getClassLoader().getResource()
- ClassLoader.getSystemClassLoader().getResource()
- Thread.currentThread().getContextClassLoader().getResource()
其中后面的三种方式,都是使用ClassLoader,所以可以归结为一种。归纳起来其时就是三种:
- Class.getResource()
- ClassLoader.getResource()
- ResourceBundle.getBundle ()
上面的两种方式有一些细微的不同:
Class.getResource():
这个使用方式和具体的类有关,所以可以方便得到当前类所在的包下的资源。例如:
String.getResource("myfile.txt"):它取得的资源路径就是“java/lang/myfile.txt
”(因为String类在java.lang包下)。或者使用"../myfile.txt"的方式。
它也可以使用绝对路径,例如:
String.getResource("/myfile.txt"):它取得的资源路径就是“/myfile.txt
”。这个表示从根路径下取得资源。
注意:如果你不是想从相对路径下(例如当前包下,或上层包下)取得资源,不必使用这个方式。当然,如果你的包名可能会改,还是使用这种方式。因为如果你要使用下面的那种方式的话,可能会需要改动其它的代码。
ClassLoader.getResource():
这个类代表的是某一个包下具体的类,所以它取得资源时,默认就是根路径。也就是说使不使用“/”,结果都是一样的。下面的两个结果都是一样的。
ClassLoader.getResource("myfile.txt")
ClassLoader.getResource("/myfile.txt")
注意:Tomcat7及以下的版本中,上面的说的结果一样的这两种方式,运行的结果可能不一样。具体请看最上面参考的的文章。
还有,我使用"ClassLoader.getResource("/myfile.txt")"这种方式时,返回的是null,不知道为什么。。。
ResourceBundle.getBundle ():
这种方式下,路径默认也是根路径。但参数的书写方式和上面有点不同:
ResourceBundle.getBundle ("pkgOne.pkgTwo.file");
和上面两种方式不同的是:1,包之间不用"/"来分隔,改用"."来分隔。2,默认带有".properties"后缀,也就是说上面文件实际上应该是:"pkgOne/pkgTow/file.properties"。
下面是三种方式的不同点的总结:
Method
Parameter format | Lookup failure behavior | Usage example | |
ClassLoader. getResourceAsStream() | "/"-separated names; no leading "/" (all names are absolute) | Silent (returns null ) | this.getClass().getClassLoader() .getResourceAsStream ("some/pkg/resource.properties") |
Class. getResourceAsStream() | "/"-separated names; leading "/" indicates absolute names; all other names are relative to the class's package | Silent (returns null ) | this.getClass() .getResourceAsStream ("resource.properties") |
ResourceBundle. getBundle() | "."-separated names; all names are absolute; .properties suffix is implied | Throws unchecked
| ResourceBundle.getBundle ("some.pkg.resource") |