如何将java.util.Properties写入具有排序键的XML?

2022-09-04 05:06:31

我想将属性文件存储为 XML。在执行此操作时,有没有办法对键进行排序,以便生成的 XML 文件将按字母顺序排列?

String propFile = "/path/to/file";
Properties props = new Properties();
/*set some properties here*/
try {
    FileOutputStream xmlStream = new FileOutputStream(propFile);
    /*this comes out unsorted*/
    props.storeToXML(xmlStream,"");
} catch (IOException e) {
    e.printStackTrace();
}

答案 1

这是一个快速而肮脏的方法来做到这一点:

String propFile = "/path/to/file";
Properties props = new Properties();

/* Set some properties here */

Properties tmp = new Properties() {
  @Override
  public Set<Object> keySet() {
    return Collections.unmodifiableSet(new TreeSet<Object>(super.keySet()));
  }
};

tmp.putAll(props);

try {
    FileOutputStream xmlStream = new FileOutputStream(propFile);
    /* This comes out SORTED! */
    tmp.storeToXML(xmlStream,"");
} catch (IOException e) {
    e.printStackTrace();
}

以下是注意事项:

  • tmp 属性(一个匿名子类)不履行属性的协定。

例如,如果您获取了它并尝试从中删除元素,则会引发异常。因此,不要允许此子类的实例逃逸!在上面的代码段中,您永远不会将其传递给另一个对象或将其返回给具有合法期望的调用方,该调用方合法地期望它满足属性的协定,因此它是安全的。keySet

  • Properties.storeToXML 的实现可能会更改,从而导致它忽略 keySet 方法。

例如,将来的版本或 OpenJDK 可以使用 的方法代替 。这就是为什么类应该始终记录它们的“自我使用”(有效的Java Item 15)的原因之一。但是,在这种情况下,可能发生的最坏情况是输出将恢复为未排序。keys()HashtablekeySet

  • 请记住,属性存储方法将忽略任何“默认”条目。

答案 2

以下是为存储和生成排序输出的方法:Properties.store(OutputStream out, String comments)Properties.storeToXML(OutputStream os, String comment)

Properties props = new Properties() {
    @Override
    public Set<Object> keySet(){
        return Collections.unmodifiableSet(new TreeSet<Object>(super.keySet()));
    }

    @Override
    public synchronized Enumeration<Object> keys() {
        return Collections.enumeration(new TreeSet<Object>(super.keySet()));
    }
};
props.put("B", "Should come second");
props.put("A", "Should come first");
props.storeToXML(new FileOutputStream(new File("sortedProps.xml")), null);
props.store(new FileOutputStream(new File("sortedProps.properties")), null);

推荐