能保存Properties文件注释的Properties工具类

        今天遇到一个小需求:由于java.util.Properties读取属性文件时会忽略注释,当写回去的时候,注释都没了。恰好一个项目中的配置文件会在部署后被某个Java程序修改一下,但修改了之后注释全没了,可能会给以后的参数调整带来困难。所以要解决这个问题。
        正好最近在看Java集合框架类库,干脆搞它一把。但是时间有限,也不能从头搞起,那就基于Properties搞搞看。
        先确定要解决什么问题。首要问题是,读取一个属性文件,然后写回去,注释全没了。从Properties代码片段里找一下原因:
    public synchronized void load(InputStream inStream) throws IOException {
        load0(new LineReader(inStream));
    }

        当Properties从一个字节流中加载属性时,会通过一个行读取器java.util.Properties.LineReader。
    /* Read in a "logical line" from an InputStream/Reader, skip all comment
     * and blank lines and filter out those leading whitespace characters 
     * (\u0020, \u0009 and \u000c) from the beginning of a "natural line". 
     * Method returns the char length of the "logical line" and stores 
     * the line in "lineBuf". 
     */
    class LineReader {
        public LineReader(InputStream inStream) {
            this.inStream = inStream;
            inByteBuf = new byte[8192]; 
	}

        从行读取器的注释上看,是在读行的时候跳过了comment。
        要解决这个问题好办,只要修改下这个行读取器,把comment放行就哦了。但是光把comment放开,那怎么保存呢?java.util.Properties扩展自java.util.Hashtable,键值对存在java.util.Hashtable.Entry里。这货也没法扩展,只能想办法在其他地方把comment存起来。首要问题有解决方案了。
        还有一个小问题,由于java.util.Properties扩展自java.util.Hashtable,并不保证key的顺序。所以读取然后写回文件,里面属性的顺序都乱了。想个办法保证一下顺序,猛然想到了java.util.LinkedHashMap,有木有,这个太合适了。
        最后赶紧写了一下,代码片段如下。
/** 
 *   CommentedProperties
 *   针对Properties进行扩展的工具类
 *   
 *   扩展的两个主要功能:
 *   1.对Properties文件中注释的保存。
 *       CommentedProperties在读取和保存Properties文件时,会将其注释
 *       一起读取保存。CommentedProperties中会提供方法来根据key获取
 *       相应注释。在CommentedProperties中添加一个K-V对时,也会提供
 *       添加相应注释的方法。
 *       
 *   2.对Properties文件中Key值顺序的保证。
 *       CommentedProperties会保证Key的顺序。从一个Properties文件中
 *       读取所有K-V对,保存到另一个Properties文件时,Key的顺序不会
 *       改变。
 *       
 *
 * @author BrokenDreams
 */
public class CommentedProperties{

	/**
	 * 内部属性表
	 */
	private final Properties props;

	/**
	 * 保存key与comment的映射,
	 * 同时利用这个映射来保证key的顺序。
	 */
	private final LinkedHashMap<String, String> keyCommentMap = new LinkedHashMap<String, String>();

	private static final String BLANK = "";

	public CommentedProperties() {
		super();
		props = new Properties();
	}

	public CommentedProperties(Properties defaults) {
		super();
		props = new Properties(defaults);
	}

        应该有更好的方式解决这个问题,但解决问题的同时顺序熟悉一下JDK相关类的代码页不是坏事,呵呵。这个类基本上能用了,可能还有很多可改进的地方。
        代码见附件,有用得着的可以下载来看看,HOHO,回家!

你可能感兴趣的:(properties)