使用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();
}
}
12345678910111213141516
使用该方法写配置文件有一弊处:导致配置文件里面的配置项变得混乱。
假设现有配置文件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
123456789101112
假设需要使用上述方法,将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
12345678910111213
可以看到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();
}
}
123456789
依然时同一个配置文件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();
}}
12345678910111213141516
使用此方法将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();
}
}
123456789101112131415
用该方法将key9的值改回value9。
改前:
改后: 此方法在运行过程中会出现下面的信息,这似乎是目前存在的梗,但不影响程序实际工作。 使用的jar:
调用save()方法就可以保存你的配置:
PropertiesConfiguration config = new PropertiesConfiguration("mypro.properties"); config.setProperty("lbl_username", "tttt"); config.save();
你也可以复制一份配置保存到另外一个文件:
PropertiesConfiguration config = new PropertiesConfiguration("mypro.properties"); config.setProperty("lbl_username", "test"); config.save("mypro_backup.properties");
如果你不想在配置信息改变之后费心的手动保存文件,你可以激活自动保存模式:
PropertiesConfiguration config = new PropertiesConfiguration("mypro.properties"); config.setAutoSave(true); config.setProperty("lbl_username", "gggg");
Lists and Arrays
Commons Configuration 可以很轻松的返回一组值, 例如你的文件包含了用逗号分割的一组数据:
# city list
city = USA, China, English
你不用手动拆分字符串,可以直接作为数组返回:
String[] colors = config.getStringArray("city");
另外一种作法, 你可以通过多行的同名键值对,来返回一组值。
# city list
city = USA; city = China; city = English;
变量窜改
如果你熟悉Ant或者Maven,你肯定已经用到 (像 ${token}
)这样可以在配置文件被加载时自动扩充的变量。 Commons Configuration 也支持这样的特性, 下面是个示例:
application.name = Killer App application.version = 1.6.2 application.title = ${application.name} ${application.version}
特殊字符
如果你需要用到一些特殊字符,比如换行符,制表符,或者unicode字符,你需要进行字符转义,字符串分隔符(默认的是逗号“,”)也需要被转义 :
key = This \n string \t contains \, escaped \\ characters \u0020
3 总结
apache commons configuration可以读写配置各种形式的配置文件,2.7版本甚至可以自动保存和自动重载,还有很多诸如记录等功能。 本文主要讲写配置文件部分,其它部分可参考下列网址。
4 参考文献
https://stackoverflow.com/questions/565932/a-better-class-to-update-property-files/565996#565996http://commons.apache.org/proper/commons-configuration/userguide/user_guide.htmlhttps://mvnrepository.com/artifact/org.apache.commons/commons-configuration2https://mvnrepository.com/artifact/commons-configuration/commons-configurationhttps://issues.apache.org/jira/browse/CONFIGURATION-629
————————————————
版权声明:本文为CSDN博主「蜡笔小达新」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_31305965/article/details/104970730