欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java解析Properties.xml

程序员文章站 2022-07-14 16:59:37
...

最近在一个Java项目中,使用了一个解析Properties.xml的文件,觉得好用,研究了一下源码优化了一下,并分享出来。

需要准备的东西:一个Java的编译器,一个jar包:commons-io.jar

首先,我们先来看看项目的文件路径

 

Java解析Properties.xml

新建一个名称为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>

编辑测试代码,运行测试

Java解析Properties.xml

 到此,本章的内容已经结束,又问题可以在评论区留言,有吐槽也可以留下,告辞!