java配置properties文件_关于Java配置文件properties的学习

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

b1524955ac56900ceb3764e558a7835e.png

Java在对*.properties文件进行操作的时候,实际上是通过IO对文档进行逐行的扫描,然后将文中非注释的部分存放在一个properties对象中。Properties 实际上是继承了hashtable,实现了Map接口。可以这样理解,它是进行了进一步封装的HashMap。存放到properties中后,可以对properties进行一系列的操作,此时的数据保存在内存中。最后,当需要保存数据的时候,是将properties中所有的键值重新写入到文件中去。 对properties文件的操作,jdk提供了一系列的API。一下是一个工具类,实现了对properties文件的增删查改的功能。

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 package com.sean.file.properties;

2

3 import java.io.File;

4 import java.io.FileOutputStream;

5 import java.io.IOException;

6 import java.io.InputStreamReader;

7 import java.io.OutputStreamWriter;

8 import java.io.UnsupportedEncodingException;

9 import java.util.Enumeration;

10 import java.util.HashMap;

11 import java.util.Map;

12 import java.util.Properties;

13 /**

14 * Java 操作Properties的工具类

15 * 实现功能:

16 * 1、Properties文件的增删查改功能

17 * 2、解决读写中文乱码问题

18 * @author Sean

19 *

20 */

21 public class PropertiesUtil {

22

23 /**

24 * Properties地址值,不需要加根标记"/"

25 */

26 private String src = "";

27 private InputStreamReader inputStream = null;

28 private OutputStreamWriter outputStream = null;

29 private String encode="utf-8";

30 public Properties properties ;

31

32 /**

33 * 默认构造函数

34 */

35 public PropertiesUtil() {

36 }

37

38 /**

39 * 构造函数

40 *

41 * @param src 传入Properties地址值,不需要加根标记"/"

42 */

43 public PropertiesUtil(String src) {

44 this.src = src;

45 }

46

47

48 /**

49 * 构造函数,提供设置编码模式

50 * @param src 传入Properties地址值,不需要加根标记"/"

51 * @param encode 传入对应的编码模式,默认是utf-8

52 */

53 public PropertiesUtil(String src, String encode) {

54 this(src);

55 this.encode = encode;

56 }

57

58 /**

59 * 加载properties文件

60 * @author Sean

61 * @date 2015-6-5

62 * @return 返回读取到的properties对象

63 */

64 public Properties load(){

65 if(src.trim().equals("")){

66 throw new RuntimeException("The path of Properties File is need");

67 }

68 try {

FileInputStream fis = new FileInputStream(src);

69 inputStream=new InputStreamReader(fis/*ClassLoader.getSystemResourceAsStream(src)*/,encode);

70 } catch (UnsupportedEncodingException e1) {

71 e1.printStackTrace();

72 }

73 properties=new Properties();

74 try {

75 properties.load(inputStream);

76 } catch (IOException e) {

77 e.printStackTrace();

78 }

79 return properties;

80 }

81

82 /**

83 * 将配置写入到文件

84 * @author Sean

85 * @date 2015-6-5

86 * @throws Exception

87 */

88 public void write2File() throws Exception{

89 //获取文件输出流

90 outputStream=new OutputStreamWriter(new FileOutputStream(new File(src/*ClassLoader.getSystemResource(src).toURI()*/)),encode);

91 properties.store(outputStream, null);

92 close();

93 }

94

95

96 /**

97 * 通过关键字获取值

98 * @author Sean

99 * @date 2015-6-5

100 * @param key 需要获取的关键字

101 * @return 返回对应的字符串,如果无,返回null

102 */

103 public String getValueByKey(String key){

104 properties=load();

105 String val =properties.getProperty(key.trim());

106 close();

107 return val;

108

109 }

110

111 /**

112 * 通过关键字获取值

113 * @author Sean

114 * @date 2015-6-5

115 * @param key 需要获取的关键字

116 * @param defaultValue 若找不到对应的关键字时返回的值

117 * @return 返回找到的字符串

118 */

119 public String getValueByKey(String key ,String defaultValue){

120 properties=load();

121 String val =properties.getProperty(key.trim(),defaultValue.trim());

122 close();

123 return val;

124 }

125

126 /**

127 * 关闭输入输出流

128 * @author Sean

129 * @date 2015-6-5

130 */

131 public void close(){

132 try {

133 if(inputStream!=null){inputStream.close();}

134 if(outputStream!=null){outputStream.close();}

135 } catch (IOException e) {

136 e.printStackTrace();

137 }

138 }

139

140 /**

141 * 获取Properties所有的值

142 * @author Sean

143 * @date 2015-6-5

144 * @return 返回Properties的键值对

145 */

146 public Map getAllProperties(){

147 properties=load();

148 Map map=new HashMap();

149 //获取所有的键值

150 Enumeration enumeration=properties.propertyNames();

151 while(enumeration.hasMoreElements()){

152 String key=(String) enumeration.nextElement();

153 String value=getValueByKey(key);

154 map.put(key, value);

155 }

156 close();

157 return map;

158 }

159

160 /**

161 * 往Properties写入新的键值

162 * @author Sean

163 * @date 2015-6-5

164 * @param key 对应的键

165 * @param value 对应的值

166 */

167 public void addProperties(String key,String value){

168 properties=load();

169 properties.put(key, value);

170 try {

171 write2File();

172 } catch (Exception e) {

173 e.printStackTrace();

174 }

175 }

176

177 /**

178 * 添加Map中所有的值

179 * @author Sean

180 * @date 2015-6-5

181 * @param map 对应的键值对集合

182 */

183 public void addAllProperties(Map map){

184 properties=load();

185 properties.putAll(map);

186 try {

187 write2File();

188 } catch (Exception e) {

189 e.printStackTrace();

190 throw new RuntimeException("write fail");

191 }

192 }

193

194 /**

195 * 更新配置文件

196 * @author Sean

197 * 2015-6-5

198 * @param key 需要更新的键值

199 * @param value 对应的值

200 */

201 public void update(String key,String value){

202 properties=load();

203 if(!properties.containsKey(key)){

204 throw new RuntimeException("not such key");

205 }

206 properties.setProperty(key, value);

207 try {

208 write2File();

209 } catch (Exception e) {

210 e.printStackTrace();

211 throw new RuntimeException("write fail");

212 }

213 }

214

215 /**

216 * 删除某一键值对

217 * @author Sean

218 * 2015-6-5

219 * @param key 对应的键值

220 */

221 public void deleteKey(String key){

222 properties=load();

223 if(!properties.containsKey(key)){

224 throw new RuntimeException("not such key");

225 }

226 properties.remove(key);

227 try {

228 write2File();

229 } catch (Exception e) {

230 e.printStackTrace();

231 throw new RuntimeException("write fail");

232 }

233 }

234

235 /**

236 * 设置path值

237 * @author Sean

238 * @date 2015-6-5

239 * @param src 对应文件值

240 */

241 public void setSrc(String src) {

242 this.src = src;

243 }

244 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

基本上,常用的对properties的操作采用这个工具类都能完成。值得注意的是,因为程序在对properties进行扫描的时候,忽略了注释的内容,而当重新写内容入文字的时候,程序也只会将properties中的值写入,这样会注释丢失的情况。这种情况,网上有人的解决方案是自己新建一个继承了properties的类,然后将程序读取到的信息包括注释放入到LinkedHashMap中,这样就可以保存注释了。

不过,同样的功能,通过Apache 上的开源项目commons-configuration也能实现。commons-configuration 主要是实现对如xml, properties等配置文件操作的API。通过它,同样能实现对properties的操作,同时,在操作的时候,也可以保存文件中的注释。

在使用commons-configuration进行properties的文件操作的时候,不仅需要导入commons-configuration.jar 包,还需要导入另外几个依赖包才能实现。

34c175a6baf74dc2d45aea0d50912590.png

以下是本能采用commons-configuration提供的api进行properties操作的一个Demo

48304ba5e6f9fe08f3fa1abda7d326ab.png

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();

}

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

可以看出,commons-configuration提供的api操作起来简单多了。可是,因为commons-configuration是国外的开源项目,所以其对中文的支持存在一些问题。尽管API中提供了设置字符编码的功能,但是还是没有能够非常好的解决中文的问题。相对而言,原生的API实现起来比较的简单。

最后做下总结,关于对properties 的操作,jdk和commons-configuration都提供了较好的支持,关于使用原生还是框架,应该根据具体条件而定。不过我们在不重复造轮的情况下,还是应该保持对原理的探讨

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值