读取properties属性文件总共有两种方式,ResourceBundle和Properties。下面,说说这两种方式的区别:
1、通过ResourceBundle读取.properties文件可避免路径问题。在jar里读取.properties文件时,总是出现找不到文件路径,后来用ResourceBundle读取.properties文件即可避免路径问题。
2、无论系统的默认编码是什么,ResourceBundle在读取properties文件时统一使用iso8859-1编码。因此,如果在默认编码为 GBK的系统中编写了包含中文的properties文件,经由ResourceBundle读入时,必须转换为GBK格式的编码,否则不能正确识别。
3、Properties的处理方式是将其作为一个映射表,而且这个类表示了一个持久的属性集,他是继承HashTable这个类。
4、ResourceBundle本质上也是一个映射,但是它提供了国际化的功能。所以,一般来说,ResourceBundle类通常是用于针对不同的语言来使用的属性文件。而如果你的应用程序中的属性文件只是一些配置,并不是针对多国语言的目的。那么使用Properties类就可以了。
5、这两个类都是读取properties格式的文件的,而Properties同时还能用来写文件。
通过ResourceBundle读取properties属性文件
package com.zlb;
import java.util.ResourceBundle;
/**
* @deprecated 读取配置文件信息
* @author sunny
*
*/
public class ConfigInfo {
private static ResourceBundle cache = null;
static{
try {
cache = ResourceBundle.getBundle("zlb");
} catch (RuntimeException e) {
e.printStackTrace();
}
}
public String getValue(String key){
return cache.getString(key);
}
public static void main(String[] agrc){
System.out.println(new ConfigInfo().getValue("name"));
System.out.println(new ConfigInfo().getValue("age"));
System.out.println(new ConfigInfo().getValue("sex"));
}
}
通过Properties操作属性文件
package com.zlb;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Properties;
/**
* 访问资源文件
* @author sunny
*
*/
public class PropertyEditor {
public static void main(String[] args) throws Exception {
Properties prop = new Properties();// 属性集合对象
FileInputStream fis = new FileInputStream("prop.properties");// 属性文件输入流 (相对于根目录下的文件名,要加上包名 “src/prop.properties”)
prop.load(fis);// 将属性文件流装载到Properties对象中
fis.close();// 关闭流
// 获取属性值,sitename已在文件中定义
System.out.println("获取属性值:sitename=" + prop.getProperty("sitename"));
// 获取属性值,country未在文件中定义,将在此程序中返回一个默认值,但并不修改属性文件
System.out.println("获取属性值:country=" + prop.getProperty("country", "中国"));
// 修改sitename的属性值
prop.setProperty("sitename", "中国");
// 添加一个新的属性studio
prop.setProperty("studio", "Boxcode Studio");
// 文件输出流
FileOutputStream fos = new FileOutputStream("prop.properties");
// 将Properties集合保存到流中
prop.store(fos, "Copyright (c) Boxcode Studio");
fos.close();// 关闭流
}
}
属性文件prop.properties:
sitename=\u4E2D\u56FD
studio=Boxcode Studio
country=china
通过Properties访问属性文件的话,由于I/O的速度比较慢,如果负责读取配置文件的class是在每次用到这些配置项的时候去读文件,就容易成为性能上的瓶颈。为避免这样的情况,可以在初始化的时候就把配置项一次全部读入,并保存在静态成员变量中。这里,你可以参考我的另外一篇文章http://blog.csdn.net/zlb824/article/details/7192320
这里再补充一个知识点:MessageFormat
MessageFormat用来格式化一个消息,通常是一个字符串,比如:
String str = "I'm not a {0}, age is {1,number,short}", height is {2,number,#.#};
而MessageFormat可以格式化这样的消息,然后将格式化后的字符串插入到模式中的适当位置,比如:
将str中的{0}用"pig"替换,{1,number,short}用数字8替换,{2,number,#.#}用数字1.2替换。
那么最终用户得到的是一个格式化好的字符串"I'm not a pig, age is 8, height is 1.2"。
MessageFormat本身与语言环境无关,而与用户提供给MessageFormat的模式和用于已插入参数的子格式模式有关,以生成适用于不同语言环境的消息。
还以str为例,在这个字符串中:
1、{0}和{1,number,short}和{2,number,#.#};都属于FormatElement,0,1,2是ArgumentIndex。
2、{1,number,short}里面的number属于FormatType,short则属于FormatStyle。
3、{1,number,#.#}里面的#.#就属于子格式模式。
import java.text.MessageFormat;
import java.util.Date;
public class MessageFormatTest {
/**
* @param args
*/
public static void main(String[] args) {
int planet = 7;
String event = "a disturbance in the Force";
String result = MessageFormat.format(
"At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.",
planet, new Date(), event);
System.out.println(result);
}
}
参考资料
http://blog.csdn.net/rujielaisusan/article/details/4571148
http://blog.csdn.net/w244802/article/details/7072768