Properties
在编写应用程序的时候,经常需要读写配置文件。例如,用户的设置:
# 上次最后打开的文件://#号后面的代表注释
last_open_file=/data/hello.txt
# 自动保存文件的时间间隔:
auto_save_interval=60
配置文件的特点是,它的Key-Value
一般都是String-String
类型的,因此我们完全可以用Map<String, String>
来表示它。
因为配置文件非常常用,所以Java集合库提供了一个Properties
来表示一组“配置”。由于历史遗留原因,Properties
内部本质上是一个Hashtable
,但我们只需要用到Properties
自身关于读写配置的接口。
读取配置文件
用Properties读取配置文件非常简单。Java默认配置文件以.properties为扩展名,每行以key=value表示,以#课开头的是注释。以下是一个典型的配置文件:
# setting.properties
last_open_file=/data/hello.txt
auto_save_interval=60
可以从文件系统读取这个.properties
文件:
用Properties读取配置文件,一共有三步:
①创建Properties
实例;
②调用load()
读取文件;
③调用getProperty()
获取配置。(当我们调用的key不存在时,系统会返回默认值为null
,当然我们也可以自定义返回值,在getProperty()
里用逗号隔开写上未找到时你期望的返回值即可)
String f = "setting.properties";
Properties props = new Properties();
props.load(new java.io.FileInputStream(f));//f代表我们要读入的文件
String filepath = props.getProperty("last_open_file");
String interval = props.getProperty("auto_save_interval", "120");//这里的120就是自定义的一个返回值。
还可以从classpath
读取.properties
文件,因为load(InputStream)
方法接收一个InputStream
实例,表示一个字节流,它不一定是文件流,也可以是从jar
包中读取的资源流:
Properties props = new Properties();
props.load(getClass().getResourceAsStream("/common/setting.properties"));
如果有多个.properties
文件,可以反复调用load()
读取,后读取的key-value
会覆盖已读取的key-value
(这个过程可用于在适配不同机器时更改默认值)
Properties props = new Properties();
props.load(getClass().getResourceAsStream("/common/setting.properties"));
props.load(new FileInputStream("C:\\user\\setting.properties"));
上面的代码演示了Properties
的一个常用用法:可以把默认配置文件放到classpath
中,然后,根据机器的环境编写另一个配置文件,覆盖某些默认的配置。
Properties
设计的目的是存储String-string
类型的key-value
,但Properties实际上是从Hashtable
派生的,它的设计实际上是有问题的,但是为了保持兼容性,现在已经没法修改了。除了getProperty()
和setProperty()
方法外,还有从Hashtable
继承下来的get()
和put()
方法,这些方法的参数签名是Object
,我们在使用Properties
的时候,不要去调用这些从Hashtable
继承下来的方法。
写入配置文件
如果通过setProperty()修改了Properties实例,可以把配置写入文件,以便下次启动时获得最新配置。写入配置文件使用store()方法:
Properties props = new Properties();
props.setProperty("url", "http://www.baidu.com");
props.setProperty("language", "Java");
props.store(new FileOutputStream("C:\\user\\setting.properties"), "这里是你要写入的properties注释");
编码
早期版本的Java规定.properties
文件编码是ASCII
编码,如果涉及到中文就必须用name=\u4e2d\u6587
来表示,非常别扭。从JDK9
开始,Java的.properties
文件可以使用UTF-8
编码了。
但由于load(InputStream)
默认总是以ASCII
编码读取字节流,所以会导致读到乱码。我们需要用另一个重载方法load(Reader)
读取:
Properties props = new Properties();
props.load(new FileReader("settings.properties", StandardCharsets.UTF_8));
就可以正常读取中文。InputStream
和Reader
的区别是一个是字节流,一个是字符流。字符流在内存中已经以char
类型表示了,不涉及编码问题。