关于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) ...
随机推荐
- Unable to start activity异常的解决方案
当时我正在测试一个用户身份验证组件.使用的是android内置的Accounts API.当时的情况是,需要在App2中调用App1的用户身份验证组件,但是不知道为什么登入界面总是无法正常开启.后来我 ...
- TCP通讯处理粘包详解
TCP通讯处理粘包详解 一般所谓的TCP粘包是在一次接收数据不能完全地体现一个完整的消息数据.TCP通讯为何存在粘包呢?主要原因是TCP是以流的方式来处理数据,再加上网络上MTU的往往小于在应用处理的 ...
- selenium-webdriver(python) 11
selenium-webdriver(python) (十一) 本节重点: 控制滚动条到底部 有时候我们需要控制页面滚动条上的滚动条,但滚动条并非页面上的元素,这个时候就需要借助js是来进行操作.一般 ...
- Ping其他电脑ping不通的解决方法
要想Ping通其他电脑,首先要看被PING的电脑,是否允许PING. 一.在被PING电脑操作系统为XP下分为:1.被PING 电脑关闭了防火墙,就完全可以PING通:2.被PING 电脑开了防火墙, ...
- ICMP:internet 控制报文协议
ICMP:internet 控制报文协议 1.概述 ICMP是(Internet Control Message Protocol)Internet控制报文协议.它是TCP/IP协议族的一个 ...
- POJ 3342 - Party at Hali-Bula 树型DP+最优解唯一性判断
好久没写树型dp了...以前都是先找到叶子节点.用队列维护来做的...这次学着vector动态数组+DFS回朔的方法..感觉思路更加的清晰... 关于题目的第一问...能邀请到的最多人数..so ea ...
- POJ 3900 The Robbery
大意:和背包的问题相似,第 i 个箱子有 i 颗钻石.钻石的重量,价值给出.然后再M的重量下背尽量多价值的钻石. 思路:直接暴搜然后剪枝.因为数据范围的原因无法用DP. #include <cs ...
- [置顶] 让我爱恨的ThinkPHP Relation
还记得第一次用ThinkPHP的relation,做了一个关联查询,觉得特别好用.有那么一天尝试着用关联插入,怎么插,都插不进,我插,我擦! 后来在龙哥的指点下算是成功的实践了一次,后来怎么用都不顺, ...
- JAX-WS创建和处理SOAP消息
JAX-WS规范是一组XML web services的JAVA API,在 JAX-WS中,一个远程调用可以转换为一个基于XML的协议例如SOAP,在使用JAX-WS过程中,开发者不需要编写任何生成 ...
- [ios2]iOS 图片与内存 【转】
第一种解决方法:选择适当的加载方式 在程序的开发过程中,经常会用到很多的图片,适当的选择加载图片的方式就显得格外的重要,如果选择不得当,很容易造成内存吃紧而引起程序的崩溃. 这里介绍一下几种常见的加载 ...