getResourceAsStream--->

-----------------ResourceBundle读取配置文件-------------------------------java

测试及验证

下面咱们来模拟一个多语言的环境web

定义四个资源文件:res_en_US.properties、res_zh_CN.properties、res_zh.properties、res.propertiesapp

res_en_US.properties:cancelKey=cancel测试

res_zh_CN.properties:cancelKey=\u53D6\u6D88(取消)
spa

res_zh.properties:cancelKey=\u53D6\u6D88zh(取消zh)
code

res.properties:cancelKey=\u53D6\u6D88default(取消default)
orm


命名规则按照:资源名+_语言_国别.properties,每一个资源文件中定义了本地化的信息,那么系统如何取到对应的资源文件呢?xml

ResourceBundle bundle = ResourceBundle.getBundle("res", new Locale("zh", "CN"));


其中new Locale("zh", "CN");这个对象就告诉了程序你的本地化信息,就拿这个来讲吧:程序首先会去classpath下寻找res_zh_CN.properties对象

若不存在,那么会去找res_zh.properties,若仍是不存在,则会去寻找res.properties,要仍是找不到的话,那么就该抛异常了:MissingResourceException资源

咱们能够来写个测试程序验证一下:


package bundle.test;

import java.util.Locale;
import java.util.ResourceBundle;

public class BundleTest {

	public static void main(String args[]) {
		ResourceBundle bundle = ResourceBundle.getBundle("res", new Locale("zh", "CN"));
		String cancel = bundle.getString("cancelKey");
		System.out.println(cancel);
		
		bundle = ResourceBundle.getBundle("res", Locale.US);
		cancel = bundle.getString("cancelKey");
		System.out.println(cancel);
		
		bundle = ResourceBundle.getBundle("res", Locale.getDefault());
		cancel = bundle.getString("cancelKey");
		System.out.println(cancel);

		bundle = ResourceBundle.getBundle("res", Locale.GERMAN);
		cancel = bundle.getString("cancelKey");
		System.out.println(cancel);
	}
}



输出:

取消
cancel
取消
取消


这里前三个都在咱们的预期范围以内,可是最后一个GERMAN,应该会去使用res.properties这个资源包吧?怎么使用了res_zh_CH.properties?

原来ResourceBundle为咱们提供了一个fallback(也就是一个备用方案),这个备用方案就是根据当前系统的语言环境来获得的本地化信息。

因此如果找不到GERMAN的,以后就会去找CHINA了,因此找到了res_zh_CH.properties这个资源包

这点我也是看了源代码才明白的,下面就贴上一些关键的源代码:

ResourceBundle baseBundle = null;
	for (Locale targetLocale = locale;
	     targetLocale != null;
	     targetLocale = control.getFallbackLocale(baseName, targetLocale)) {// 这里就是去拿备用方案的
	    // do something 咱们暂时不关心
	}


跟踪control.getFallbackLocale(baseName, targetLocale)看看备用方案究竟是什么?

public Locale getFallbackLocale(String baseName, Locale locale) {
	    if (baseName == null) {
		throw new NullPointerException();
	    }
	    Locale defaultLocale = Locale.getDefault();
	    return locale.equals(defaultLocale) ? null : defaultLocale;
	}

 

--------------Java中getResourceAsStream的用法读取配置文件----------------------------

首先,Java中的getResourceAsStream有如下几种: 
1. Class.getResourceAsStream(String path) : path 不以’/'开头时默认是今后类所在的包下取资源,以’/'开头则是从

ClassPath根下获取。其只是经过path构造一个绝对路径,最终仍是由ClassLoader获取资源。

2. Class.getClassLoader.getResourceAsStream(String path) :默认则是从ClassPath根下获取,path不能以’/'开头,最终是由

ClassLoader获取资源。

3. ServletContext. getResourceAsStream(String path):默认从WebAPP根目录下取资源,Tomcat下path是否以’/'开头无所谓,

固然这和具体的容器实现有关。

4. Jsp下的application内置对象就是上面的ServletContext的一种实现。

其次,getResourceAsStream 用法大体有如下几种:

第一: 要加载的文件和.class文件在同一目录下,例如:com.x.y 下有类me.class ,同时有资源文件myfile.xml

那么,应该有以下代码:

me.class.getResourceAsStream("myfile.xml");

第二:在me.class目录的子目录下,例如:com.x.y 下有类me.class ,同时在 com.x.y.file 目录下有资源文件myfile.xml

那么,应该有以下代码:

me.class.getResourceAsStream("file/myfile.xml");

第三:不在me.class目录下,也不在子目录下,例如:com.x.y 下有类me.class ,同时在 com.x.file 目录下有资源文件myfile.xml

那么,应该有以下代码:

me.class.getResourceAsStream("/com/x/file/myfile.xml");

总结一下,可能只是两种写法

第一:前面有 “   / ”

“ / ”表明了工程的根目录,例如工程名叫作myproject,“ / ”表明了myproject

me.class.getResourceAsStream("/com/x/file/myfile.xml");

第二:前面没有 “   / ”

表明当前类的目录

me.class.getResourceAsStream("myfile.xml");

me.class.getResourceAsStream("file/myfile.xml");

本站公众号
   欢迎关注本站公众号,获取更多信息