前几天,公司项目中有一个需求是读取配置文件的。并且最好可以保证载入到内存中的顺序可以和配置文件里的顺序一致,可是。假设使用 jdk 中提供的 Properties 类的话,读取配置文件后。载入到内存中的顺序是随机的,不能保证和原文件的顺序一致,因此,jdk 提供的 Properties 是不行的。

背景

因为有这种需求。而 Java 的 Properties 类又不能实现,因此仅仅能想别的办法。我以前想过,在把配置文件载入到内存后,对其进行排序,但这个方法会有非常多限制,并且也有问题。

配置文件里的信息会有非常多,假设对其进行再排序的话。首先会影响系统的性能,其次,对程序的运行效率来讲,也会有一定的影响。最后,经过一番查证之后。同事找到了一篇类似的文章。

解决方式

从文章中了解到,Java 的 Properties 载入属性文件后是无法保证输出的顺序与文件里一致的,由于 Properties 是继承自 Hashtable 的, key/value 都是直接存在 Hashtable 中的,而 Hashtable 是不保证进出顺序的。

文章中已经给提供了代码,思路是继承自 Properties,覆盖原来的 put/keys,keySet,stringPropertyNames 就可以,当中用一个 LinkedHashSet 来保存它的全部 key。完整代码例如以下:

<span style="font-family:Comic Sans MS;">package com.mstar.investmeplugin;
 
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Properties;
import java.util.Set;
 
/**
 * OrderedProperties
 * @author liii
 * @date 2015-07-10
 */
public class OrderedProperties extends Properties {
 
    private static final long serialVersionUID = -4627607243846121965L;
     
    private final LinkedHashSet<Object> keys = new LinkedHashSet<Object>();
 
    public Enumeration<Object> keys() {
        return Collections.<Object> enumeration(keys);
    }
 
    public Object put(Object key, Object value) {
        keys.add(key);
        return super.put(key, value);
    }
 
    public Set<Object> keySet() {
        return keys;
    }
 
    public Set<String> stringPropertyNames() {
        Set<String> set = new LinkedHashSet<String>();
 
        for (Object key : this.keys) {
            set.add((String) key);
        }
 
        return set;
    }
}</span>

调用方法

<span style="font-family:Comic Sans MS;">Properties props = new OrderedProperties();
props.load(fileInputStream);
 
//通过 keys(), keySet() 或 stringPropertyNames 来遍历都能保证按文件里的顺序输出</span>

结束语

这样的特定的需求。曾经倒是没怎么接触过,不给通过这次的经历,发现了一点,自己的积累还是非常少,不多说了。继续努力吧。

參考:

StackOverflow

Playframework1中的还有一个实现

前几天,公司项目中有一个需求是读取配置文件的。并且最好可以保证载入到内存中的顺序可以和配置文件里的顺序一致,可是。假设使用 jdk 中提供的 Properties 类的话,读取配置文件后。载入到内存中的顺序是随机的,不能保证和原文件的顺序一致,因此,jdk 提供的 Properties 是不行的。

背景

因为有这种需求。而 Java 的 Properties 类又不能实现,因此仅仅能想别的办法。我以前想过,在把配置文件载入到内存后,对其进行排序,但这个方法会有非常多限制,并且也有问题。

配置文件里的信息会有非常多,假设对其进行再排序的话。首先会影响系统的性能,其次,对程序的运行效率来讲,也会有一定的影响。最后,经过一番查证之后。同事找到了一篇类似的文章。

解决方式

从文章中了解到,Java 的 Properties 载入属性文件后是无法保证输出的顺序与文件里一致的,由于 Properties 是继承自 Hashtable 的, key/value 都是直接存在 Hashtable 中的,而 Hashtable 是不保证进出顺序的。

文章中已经给提供了代码,思路是继承自 Properties,覆盖原来的 put/keys,keySet,stringPropertyNames 就可以,当中用一个 LinkedHashSet 来保存它的全部 key。完整代码例如以下:

<span style="font-family:Comic Sans MS;">package com.mstar.investmeplugin;
 
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Properties;
import java.util.Set;
 
/**
 * OrderedProperties
 * @author liii
 * @date 2015-07-10
 */
public class OrderedProperties extends Properties {
 
    private static final long serialVersionUID = -4627607243846121965L;
     
    private final LinkedHashSet<Object> keys = new LinkedHashSet<Object>();
 
    public Enumeration<Object> keys() {
        return Collections.<Object> enumeration(keys);
    }
 
    public Object put(Object key, Object value) {
        keys.add(key);
        return super.put(key, value);
    }
 
    public Set<Object> keySet() {
        return keys;
    }
 
    public Set<String> stringPropertyNames() {
        Set<String> set = new LinkedHashSet<String>();
 
        for (Object key : this.keys) {
            set.add((String) key);
        }
 
        return set;
    }
}</span>

调用方法

<span style="font-family:Comic Sans MS;">Properties props = new OrderedProperties();
props.load(fileInputStream);
 
//通过 keys(), keySet() 或 stringPropertyNames 来遍历都能保证按文件里的顺序输出</span>

结束语

这样的特定的需求。曾经倒是没怎么接触过,不给通过这次的经历,发现了一点,自己的积累还是非常少,不多说了。继续努力吧。

參考:

  • StackOverflow
  • Playframework1中的还有一个实现