使用apache commons configuration代替java.util.Properties写配置文件

0 需求

存在一个配置文件,用于记录一些数据,且这些数据可能通过用户界面更改,保存后重新写进配置文件。

1 原有方式

采用java.util.Properties.Properties()方法配合IO流来完成,见下方代码:

public void setProperty(String properties, String key , String newValue) {
	Properties p = new Properties();
	//try-with-resource
	try(InputStream in=new FileInputStream(properties)) {
		p.load(in);
	} catch (IOException e) {
		e.printStackTrace();
	}
	p.setProperty(key, newValue);
	//try-with-resource
	try(FileOutputStream fos=new FileOutputStream(properties)) {
		p.store(fos, null);  
	} catch (IOException e1) { 
		e1.printStackTrace();
	}
}

使用该方法写配置文件有一弊处:导致配置文件里面的配置项变得混乱。

假设现有配置文件test.properties,其中内容为:

key1 = value1
key2 = value2
key3 = value3
key4 = value4
key5 = value5
key6 = value6
key7 = value7
key8 = value8
key9 = value9
key10 = value10
key11 = value11
key12 = value12

假设需要使用上述方法,将key8的值修改为value80,则最终配置文件内的内容如下:

#Thu Mar 19 16:44:39 CST 2020
key12=value12
key11=value11
key9=value9
key10=value10
key8=value80
key7=value7
key6=value6
key5=value5
key4=value4
key3=value3
key2=value2
key1=value1

在这里插入图片描述
可以看到key8的值俨然已经变成了value80,但是配置项的顺序却被打乱了。当配置文件中存在很多配置项时,配置项的打乱将导致配置文件的可读性变差。

需要一种方法以改进此现象。

2 改进方法

使用apache commons configuration(版本1.x,依赖于commons-lang2.x版本,测试中configuration所用版本为1.10,commons-lang用的2.6版本),语法也很简单,如下。

public  void setProperty2(String properties, String key, String newValue) {
		try {
			PropertiesConfiguration config = new PropertiesConfiguration(properties);
			config.setProperty(key, newValue);
			config.save();
		} catch (ConfigurationException e) {
			e.printStackTrace();
		}
	}

依然时同一个配置文件test.properties并将key8的值改回value8,记住原来的顺序
在这里插入图片描述
调用方法后:
在这里插入图片描述
可以看到,调用方法前后,除了配置文件第一行的时间发生了变化以及需求得到了满足外,其余配置项并未出现变化。

所用的jar:
在这里插入图片描述
在这里插入图片描述

2.1 apache commons configuration 2.x

需要注意的是,apache commons configuration 2.x的语法与1.x的语法不同(测试版本为2.7,依赖于beanutils、commons-lang3、comons-text)

2.1.1 第一种方法

public static void setProperty3(String properties, String key, String newValue) {
		File file = new File(properties);
		PropertiesConfiguration config = new PropertiesConfiguration();
		PropertiesConfigurationLayout layout = config.getLayout();
		try {
			layout.load(config, new InputStreamReader(new FileInputStream(file)));
		} catch (FileNotFoundException | ConfigurationException e) {
			e.printStackTrace();
		}
		
		config.setProperty(key, newValue);
		try {
			layout.save(config, new FileWriter(properties, false));
		} catch (ConfigurationException | IOException e) {
			e.printStackTrace();
		}}

使用此方法将key9的值变为value90

改变前;
在这里插入图片描述
改变后:

在这里插入图片描述

2.1.2 第二种方法

用官方user guide 推荐的方法。

public static void setProperty2(String properties, String key, String newValue) {
		Parameters params = new Parameters();
		FileBasedConfigurationBuilder<FileBasedConfiguration> builder =
		    new FileBasedConfigurationBuilder<FileBasedConfiguration>(PropertiesConfiguration.class)
		    .configure(params.properties()
		        .setFileName(properties)
		        .setListDelimiterHandler(new DefaultListDelimiterHandler(',')));
		try {
			Configuration  config =  builder.getConfiguration();
			config.setProperty(key, newValue);
			builder.save();
		} catch (ConfigurationException e) {
			e.printStackTrace();
		}
	}

用该方法将key9的值改回value9

改前:

在这里插入图片描述
改后:
在这里插入图片描述
此方法在运行过程中会出现下面的信息,这似乎是目前存在的梗,但不影响程序实际工作。
在这里插入图片描述
使用的jar:

在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述

3 总结

apache commons configuration可以读写配置各种形式的配置文件,2.7版本甚至可以自动保存和自动重载,还有很多诸如记录等功能。
本文主要讲写配置文件部分,其它部分可参考下列网址。

4 参考文献

  1. https://stackoverflow.com/questions/565932/a-better-class-to-update-property-files/565996#565996
  2. http://commons.apache.org/proper/commons-configuration/userguide/user_guide.html
  3. https://mvnrepository.com/artifact/org.apache.commons/commons-configuration2
  4. https://mvnrepository.com/artifact/commons-configuration/commons-configuration
  5. https://issues.apache.org/jira/browse/CONFIGURATION-629
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值