Java解析Properties.xml
最近在一个Java项目中,使用了一个解析Properties.xml的文件,觉得好用,研究了一下源码优化了一下,并分享出来。
需要准备的东西:一个Java的编译器,一个jar包:commons-io.jar
首先,我们先来看看项目的文件路径
新建一个名称为P的类
新建三个包,分别为
com.XXX.parse,用来放置主类
com.xxx.test,用来测试
conf,用来放置properties.xml配置文件
话不多说,我直接来看代码
package com.zjj.parse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.InvalidPropertiesFormatException;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;
/**、
*
* 解析配置文件
* @author datou
*
*/
public class P {
//存储解析结果
private static Map<String,String> dataMap = new ConcurrentHashMap<>();
//日志对象
static Logger logger = Logger.getLogger(P.class.getName());
//读取配置文件
static {
Properties properties = new Properties();
String rootPath = P.class.getResource("/").getPath();
String configFileDirectory = rootPath + "conf/";
String configFilePath = rootPath + "conf/properties.xml";
//String path = "src/conf/properties.xml";
if(new File(configFileDirectory).exists() && new File(configFilePath).exists()) {
try {
InputStream inputStream = new FileInputStream(configFilePath);
properties.loadFromXML(inputStream);
//监控文件变化
FileAlterationObserver observer = new FileAlterationObserver("src/conf",FileFilterUtils.nameFileFilter("properties.xml"));
//添加监听器
observer.addListener(new FileAlterationListenerAdaptor() {
@Override
public void onFileChange(File file) {
InputStream inputStream;
try {
inputStream = new FileInputStream(configFilePath);
properties.loadFromXML(inputStream);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidPropertiesFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
FileAlterationMonitor monitor = new FileAlterationMonitor();
monitor.addObserver(observer);
try {
monitor.start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//清空dataMap
dataMap.clear();
//存储解析结果
properties.forEach((k,v) -> dataMap.put(""+k, ""+v));
inputStream.close();
} catch (FileNotFoundException e) {
logger.severe("配置文件"+configFilePath+"不存在!");
} catch (InvalidPropertiesFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 获取字符串
* @param key
* @return
*/
public static String S(String key) {
return dataMap.get(key);
}
/**
* 获取字符串,并指定默认值
* @param key
* @param defaultValue
* @return
*/
public static String S(String key , String defaultValue) {
String value = dataMap.get(key);
if(value == null) {
return defaultValue;
}
return value;
}
/**
* 获取整型数据
* @param key
* @return
*/
public static Integer I(String key) {
Integer value = Integer.parseInt(dataMap.get(key));
return value;
}
/**
* 获取浮点型数据
* @param key
* @return
*/
public static Double D(String key) {
Double value = Double.parseDouble(dataMap.get(key));
return value;
}
/**
* 获取字符串数组
* @param key
* @param split
* @param clzss
* @return
*/
public static String[] strArr(String key , String split , Class clzss) {
if(clzss == String.class) {
String str = dataMap.get(key);
String[] arr = str.split(split);
return arr;
}else {
return null;
}
}
}
如果看完代码,你已经知道了怎么回事,那接下来的部分就不用看了,可以留下你的优化,和批评
接下来,我来解释一下代码的内容
//存储解析结果
private static Map<String,String> dataMap = new ConcurrentHashMap<>();
//日志对象
static Logger logger = Logger.getLogger(P.class.getName());
解析完配置文件后,新建了一个dataMap存储配置信息的key-value值
logger用来打印出日志信息,例如找不到文件的目录
Properties properties = new Properties();
String rootPath = P.class.getResource("/").getPath();
String configFileDirectory = rootPath + "conf/";
String configFilePath = rootPath + "conf/properties.xml";
新建了一个Properties的对象用来解析key-value样式的xml文件
rootPath获取的是根目录,configFileDirectory是配置文件放置的目录,configFilePath为文件的路径,如果文件
目录或者文件的路径是不存在的,就不执行解析
InputStream inputStream = new FileInputStream(configFilePath);
properties.loadFromXML(inputStream);
获取到文件的的输入流,然后执行Properties的loadFromXML方法,到这里,配置文件的信息就读取到properties对象里头
//监控文件变化
FileAlterationObserver observer = new FileAlterationObserver("src/conf",FileFilterUtils.nameFileFilter("properties.xml"));
//添加监听器
observer.addListener(new FileAlterationListenerAdaptor() {
@Override
public void onFileChange(File file) {
InputStream inputStream;
try {
inputStream = new FileInputStream(configFilePath);
properties.loadFromXML(inputStream);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidPropertiesFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
FileAlterationMonitor monitor = new FileAlterationMonitor();
monitor.addObserver(observer);
try {
monitor.start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
FileAlterationObserver 是一个监控文件的监控器,添加一个文件修改的监听事件,如果文件发生了变化,则重新执行loadXML的方法
//清空dataMap
dataMap.clear();
//存储解析结果
properties.forEach((k,v) -> dataMap.put(""+k, ""+v));
inputStream.close();
先清空dataMap,遍历properties对象,将配置的文件的信息存进dataMap,关闭输入流
到此配置文件的解析已经完成了,配置文件的信息已经存储到dataMap中
/**
* 获取字符串
* @param key
* @return
*/
public static String S(String key) {
return dataMap.get(key);
}
/**
* 获取字符串,并指定默认值
* @param key
* @param defaultValue
* @return
*/
public static String S(String key , String defaultValue) {
String value = dataMap.get(key);
if(value == null) {
return defaultValue;
}
return value;
}
/**
* 获取整型数据
* @param key
* @return
*/
public static Integer I(String key) {
Integer value = Integer.parseInt(dataMap.get(key));
return value;
}
/**
* 获取浮点型数据
* @param key
* @return
*/
public static Double D(String key) {
Double value = Double.parseDouble(dataMap.get(key));
return value;
}
/**
* 获取字符串数组
* @param key
* @param split
* @param clzss
* @return
*/
public static String[] strArr(String key , String split , Class clzss) {
if(clzss == String.class) {
String str = dataMap.get(key);
String[] arr = str.split(split);
return arr;
}else {
return null;
}
}
由于dataMap是private的,所以需要给出数据访问的接口,可以在访问数据的时候,对数据进行解析
代码中只罗列了字符串,Integer,Double,各类型的数组,可自行进行优化拓展
开始测试
先编辑配置文件的内容
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key = "str">This is a str.</entry>
<entry key = "count">100</entry>
<entry key = "arr">zjj,cbt</entry>
</properties>
编辑测试代码,运行测试
到此,本章的内容已经结束,又问题可以在评论区留言,有吐槽也可以留下,告辞!