关于Java配置文件properties的学习
在Java早期的开发中,常用*.properties文件存储一些配置信息。其文件中的信息主要是以key=value的方式进行存储,在早期受到广泛的应用。而后随着xml使用的广泛,其位置渐渐被取代,不过,目前仍有一些框架如log4J在使用它。最近在弄自己的小玩意儿的时候也用到了它,顺便加深了一下了解,在此分享。

Java在对*.properties文件进行操作的时候,实际上是通过IO对文档进行逐行的扫描,然后将文中非注释的部分存放在一个properties对象中。Properties 实际上是继承了hashtable,实现了Map接口。可以这样理解,它是进行了进一步封装的HashMap。存放到properties中后,可以对properties进行一系列的操作,此时的数据保存在内存中。最后,当需要保存数据的时候,是将properties中所有的键值重新写入到文件中去。 对properties文件的操作,jdk提供了一系列的API。一下是一个工具类,实现了对properties文件的增删查改的功能。
package com.sean.file.properties; import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* Java 操作Properties的工具类
* 实现功能:
* 1、Properties文件的增删查改功能
* 2、解决读写中文乱码问题
* @author Sean
*
*/
public class PropertiesUtil { /**
* Properties地址值,不需要加根标记"/"
*/
private String src = "";
private InputStreamReader inputStream = null;
private OutputStreamWriter outputStream = null;
private String encode="utf-8";
public Properties properties ; /**
* 默认构造函数
*/
public PropertiesUtil() {
} /**
* 构造函数
*
* @param src 传入Properties地址值,不需要加根标记"/"
*/
public PropertiesUtil(String src) {
this.src = src;
} /**
* 构造函数,提供设置编码模式
* @param src 传入Properties地址值,不需要加根标记"/"
* @param encode 传入对应的编码模式,默认是utf-8
*/
public PropertiesUtil(String src, String encode) {
this(src);
this.encode = encode;
} /**
* 加载properties文件
* @author Sean
* @date 2015-6-5
* @return 返回读取到的properties对象
*/
public Properties load(){
if(src.trim().equals("")){
throw new RuntimeException("The path of Properties File is need");
}
try {
inputStream=new InputStreamReader(ClassLoader.getSystemResourceAsStream(src),encode);
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
properties=new Properties();
try {
properties.load(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
return properties;
} /**
* 将配置写入到文件
* @author Sean
* @date 2015-6-5
* @throws Exception
*/
public void write2File() throws Exception{
//获取文件输出流
outputStream=new OutputStreamWriter(new FileOutputStream(new File(ClassLoader.getSystemResource(src).toURI())),encode);
properties.store(outputStream, null);
close();
} /**
* 通过关键字获取值
* @author Sean
* @date 2015-6-5
* @param key 需要获取的关键字
* @return 返回对应的字符串,如果无,返回null
*/
public String getValueByKey(String key){
properties=load();
String val =properties.getProperty(key.trim());
close();
return val; } /**
* 通过关键字获取值
* @author Sean
* @date 2015-6-5
* @param key 需要获取的关键字
* @param defaultValue 若找不到对应的关键字时返回的值
* @return 返回找到的字符串
*/
public String getValueByKey(String key ,String defaultValue){
properties=load();
String val =properties.getProperty(key.trim(),defaultValue.trim());
close();
return val;
} /**
* 关闭输入输出流
* @author Sean
* @date 2015-6-5
*/
public void close(){
try {
if(inputStream!=null){inputStream.close();}
if(outputStream!=null){outputStream.close();}
} catch (IOException e) {
e.printStackTrace();
}
} /**
* 获取Properties所有的值
* @author Sean
* @date 2015-6-5
* @return 返回Properties的键值对
*/
public Map<String,String> getAllProperties(){
properties=load();
Map<String,String> map=new HashMap<String,String>();
//获取所有的键值
Enumeration enumeration=properties.propertyNames();
while(enumeration.hasMoreElements()){
String key=(String) enumeration.nextElement();
String value=getValueByKey(key);
map.put(key, value);
}
close();
return map;
} /**
* 往Properties写入新的键值
* @author Sean
* @date 2015-6-5
* @param key 对应的键
* @param value 对应的值
*/
public void addProperties(String key,String value){
properties=load();
properties.put(key, value);
try {
write2File();
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 添加Map中所有的值
* @author Sean
* @date 2015-6-5
* @param map 对应的键值对集合
*/
public void addAllProperties(Map<String,String> map){
properties=load();
properties.putAll(map);
try {
write2File();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("write fail");
}
} /**
* 更新配置文件
* @author Sean
* 2015-6-5
* @param key 需要更新的键值
* @param value 对应的值
*/
public void update(String key,String value){
properties=load();
if(!properties.containsKey(key)){
throw new RuntimeException("not such key");
}
properties.setProperty(key, value);
try {
write2File();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("write fail");
}
} /**
* 删除某一键值对
* @author Sean
* 2015-6-5
* @param key 对应的键值
*/
public void deleteKey(String key){
properties=load();
if(!properties.containsKey(key)){
throw new RuntimeException("not such key");
}
properties.remove(key);
try {
write2File();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("write fail");
}
} /**
* 设置path值
* @author Sean
* @date 2015-6-5
* @param src 对应文件值
*/
public void setSrc(String src) {
this.src = src;
}
}
基本上,常用的对properties的操作采用这个工具类都能完成。值得注意的是,因为程序在对properties进行扫描的时候,忽略了注释的内容,而当重新写内容入文字的时候,程序也只会将properties中的值写入,这样会注释丢失的情况。这种情况,网上有人的解决方案是自己新建一个继承了properties的类,然后将程序读取到的信息包括注释放入到LinkedHashMap中,这样就可以保存注释了。
不过,同样的功能,通过Apache 上的开源项目commons-configuration也能实现。commons-configuration 主要是实现对如xml, properties等配置文件操作的API。通过它,同样能实现对properties的操作,同时,在操作的时候,也可以保存文件中的注释。
在使用commons-configuration进行properties的文件操作的时候,不仅需要导入commons-configuration.jar 包,还需要导入另外几个依赖包才能实现。

以下是本能采用commons-configuration提供的api进行properties操作的一个Demo
package com.sean; import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URISyntaxException; import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration; public class PropertiesUtil {
private String src="";
private PropertiesConfiguration pcf=null;
private String encode="utf-8";
/**
* 默认构造函数
*/
public PropertiesUtil(){};
/**
* 传参构造函数
* @param src 传入对应文件地址
*/
public PropertiesUtil(String src){
this.src=src;
try {
pcf=new PropertiesConfiguration(src);
} catch (ConfigurationException e) {
e.printStackTrace();
}
pcf.setEncoding(encode);
} /**
* 获取特定key的值
* @param key 对应的键值
* @return 返回对应value值,找不到返回null;
*/
public String getValue(String key){
String s=pcf.getString(key);
return s;
}
/**
* 更新对应的值
* @param key 对应的关键字
* @param value 对应的值
*/
public void updateValue(String key,String value) {
if(!pcf.containsKey(key)){
throw new RuntimeException("not such key");
}
try {
pcf.save(new FileOutputStream(new File(ClassLoader.getSystemResource(src).toURI())),"utf-8");
} catch (ConfigurationException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
} /**
* 添加键值对
* @param key 关键字
* @param value 值
*/
public void addValue(String key,String value){
pcf.addProperty(key, value);
try {
pcf.save(new FileOutputStream(new File(ClassLoader.getSystemResource(src).toURI())),"utf-8");
} catch (ConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 删除关键字
* @param key 关键字
*/
public void delValue(String key){
pcf.clearProperty(key);
try {
pcf.save(new FileOutputStream(new File(ClassLoader.getSystemResource(src).toURI())),"utf-8");
} catch (ConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
可以看出,commons-configuration提供的api操作起来简单多了。可是,因为commons-configuration是国外的开源项目,所以其对中文的支持存在一些问题。尽管API中提供了设置字符编码的功能,但是还是没有能够非常好的解决中文的问题。相对而言,原生的API实现起来比较的简单。
最后做下总结,关于对properties 的操作,jdk和commons-configuration都提供了较好的支持,关于使用原生还是框架,应该根据具体条件而定。不过我们在不重复造轮的情况下,还是应该保持对原理的探讨
关于Java配置文件properties的学习的更多相关文章
- Java配置文件Properties的读取、写入与更新操作
/** * 实现对Java配置文件Properties的读取.写入与更新操作 */ package test; import java.io.BufferedInputStream; import j ...
- 对Java配置文件Properties的读取、写入与更新操作
http://breezylee.iteye.com/blog/1340868 对Java配置文件Properties的读取.写入与更新操作 博客分类: javase properties 对Jav ...
- 实现对Java配置文件Properties的读取、写入与更新操作
/** * 实现对Java配置文件Properties的读取.写入与更新操作 */ package test; import java.io.BufferedInputStream; import j ...
- java.util.Properties类 学习笔记
学习目标: 1.认识properties文件,理解其含义,会正确创建properties文件. 2.会使用java.util.Properties类来操作properties文件. 3.掌握相对路 ...
- java配置文件properties,yml,一般文件
JAVA编写配置文件的几种方式: JAVA配置文件,一般都放在resource目录下,无论是下面提到的properties.yml还是普通的txt等文件. 在打成jar包之后,只需要jar包程序就可运 ...
- 读取java配置文件properties
java项目里很多参数都是写在配置文件properties上,如果需要读取的话,可以使用jdk里提供的Properties类进行处理. 具体写法如下: public class PropertiesC ...
- java 读写properties
网速不好:先贴上资料: Java配置文件Properties的读取.写入与更新操作 [Spring] - Property注入 http://www.360doc.com/content/14/073 ...
- freemarker遍历java.util.Properties
java.util.Properties类 学习笔记 http://trans.blog.51cto.com/503170/110227/ FreeMarker代码 <#list systemP ...
- java读取properties配置文件总结
java读取properties配置文件总结 在日常项目开发和学习中,我们不免会经常用到.propeties配置文件,例如数据库c3p0连接池的配置等.而我们经常读取配置文件的方法有以下两种: (1) ...
随机推荐
- AspNetWebApi管线中如果定义两种类型的消息处理程序(全局/路由)
AspNetWebApi管线中如果定义两种类型的消息处理程序(全局/路由) 在AspNetWebApi管线中存在两种类型的消息处理程序(Message Handler) 1.全局消息处理程序,所有的请 ...
- 一键搭键php网站环境的系统
QzzmServer v2.0正式版发布 首先,感谢网友的热情的测评及反馈,现QzzmServer 2.0正式版已发布.有些朋友反馈制作一个服务器专用版本,在下已将此列入计划中,敬请大家耐心等候. Q ...
- jquery设置元素的readonly和disabled【转】
Jquery的api中提供了对元素应用disabled和readonly属性的方法,在这里记录下.如下: 1.readonly $('input').attr("readonly&qu ...
- Extjs的学习及MIS系统实践应用
Extjs的学习及MIS系统实践应用(系列文章) 本系列文章从Extjs的实际运用出发,结合系统开发的实践经验,详细解释Extjs的基本控件及控件扩展的用法,和在平时的学习运用中一步一步查阅的资料.积 ...
- Android: Type Method 'NewStringUTF' could not be resolved
编译一个最简单的Android NDK 例子(android-ndk-r8/samples/hello-jni)出现了错误信息:Type Method 'NewStringUTF' could n ...
- linux php 安装GD库
linux下为php添加GD库的步骤如下: 一.下载 gd-2.0.33.tar.gz http://www.boutell.com/gd/ jpegsrc.v6b.tar.gz http://www ...
- 为什么MD5不能解密
MD5加密原理是散列算法,也称之为hash算法. 具体的算法很多种,我也不是很懂,写得太专业了,我们只能理解一些简单的.简单才能让人记得住. 举例说明,10除以3余数是1,4除以3的余数也是1,反过来 ...
- Effective C++ 第二版 1)const和inline 2)iostream
条款1 尽量用const和inline而不用#define >"尽量用编译器而不用预处理" Ex. #define ASPECT_R 1.653 编译器永远不会看到AS ...
- CentOS 设置 pptpd VPN 步骤
安装CentOS6.3系统参见: <CentOS 6.3安装(详细图解教程)> 安装服务: 1.安装 ADSL PPPOE #yum -y install rp-pppoe 详细设置介绍看 ...
- angularJS 自定义元素和属性
创造自定义元素和属性的方法是:directive('string',function(){ return{}; }); ①函数接收两个参数:一个字符串(指令的名字),一个函数: ②回调函数必须返回一个 ...