如何以原始顺序读取java中的属性文件

我需要读取一个属性文件并在Java中生成一个Properties类。 我这样做是通过使用:

Properties props = new Properties(); props.load(new FileInputStream(args[0])); for (Enumeration e = props.propertyNames(); e.hasMoreElements();) { } 

但是,props.propertyName返回的属性不是原始属性文件的顺序。 我知道属性只是老式的,非泛化的Hashtables。 我正在寻找一个解决方案。 任何想法? 谢谢!

您可能希望实现具有类似function的属性类。 您无法获得订单,因为您已经指出,它使用Hashtable

来自www.java2s.com的示例应该可以解决您的问题。

 import java.util.Enumeration; import java.util.Properties; import java.util.Vector; /** * View Source * * @author Brian Wing Shun Chan * */ public class OrderedProperties extends Properties { public OrderedProperties() { super (); _names = new Vector(); } public Enumeration propertyNames() { return _names.elements(); } public Object put(Object key, Object value) { if (_names.contains(key)) { _names.remove(key); } _names.add(key); return super .put(key, value); } public Object remove(Object key) { _names.remove(key); return super .remove(key); } private Vector _names; } 

您的代码将更改为:

 Properties props = new OrderedProperties(); props.load(new FileInputStream(args[0])); for (Enumeration e = props.propertyNames(); e.hasMoreElements();) { } 

您可以扩展Properties并将所有map方法委托给LinkedHashMap以保留顺序。 这是一个示例(您可能需要覆盖更多方法):

 public class LinkedProperties extends Properties{ private static final long serialVersionUID = 1L; private Map linkMap = new LinkedHashMap(); @Override public synchronized Object put(Object key, Object value){ return linkMap.put(key, value); } @Override public synchronized boolean contains(Object value){ return linkMap.containsValue(value); } @Override public boolean containsValue(Object value){ return linkMap.containsValue(value); } @Override public synchronized Enumeration elements(){ throw new UnsupportedOperationException( "Enumerations are so old-school, don't use them, " + "use keySet() or entrySet() instead"); } @Override public Set> entrySet(){ return linkMap.entrySet(); } @Override public synchronized void clear(){ linkMap.clear(); } @Override public synchronized boolean containsKey(Object key){ return linkMap.containsKey(key); } } 

类似于上面的一个,但没有维护我们自己的值列表的开销。 我们所要做的就是维护一个单独的有序键列表,并提供一个新的“keys()”方法。

 public class SequencedProperties extends Properties { private static final long serialVersionUID = -7032434592318855760L; private List keyList = new ArrayList(); @Override public synchronized Enumeration keys() { return Collections.enumeration(keyList); } @Override public synchronized Object put(Object key, Object value) { if (! containsKey(key)) { keyList.add(key); } return super.put(key, value); } @Override public synchronized Object remove(Object key) { keyList.remove(key); return super.remove(key); } @Override public synchronized void putAll(Map values) { for (Object key : values.keySet()) { if (! containsKey(key)) { keyList.add(key); } } super.putAll(values); } } 

基于LinkedHashMap的完整实现

 import java.util.*; import java.io.*; /** * Ordered properties implementation */ public class LinkedProperties extends Properties{ private static final long serialVersionUID = 1L; private Map linkMap = new LinkedHashMap(); public void clear(){ linkMap.clear(); } public boolean contains(Object value){ return linkMap.containsValue(value); } public boolean containsKey(Object key){ return linkMap.containsKey(key); } public boolean containsValue(Object value){ return linkMap.containsValue(value); } public Enumeration elements(){ throw new RuntimeException("Method elements is not supported in LinkedProperties class"); } public Set entrySet(){ return linkMap.entrySet(); } public boolean equals(Object o){ return linkMap.equals(o); } public Object get(Object key){ return linkMap.get(key); } public String getProperty(String key) { Object oval = get(key); //here the class Properties uses super.get() if(oval==null)return null; return (oval instanceof String) ? (String)oval : null; //behavior of standard properties } public boolean isEmpty(){ return linkMap.isEmpty(); } public Enumeration keys(){ Set keys=linkMap.keySet(); return Collections.enumeration(keys); } public Set keySet(){ return linkMap.keySet(); } public void list(PrintStream out) { this.list(new PrintWriter(out,true)); } public void list(PrintWriter out) { out.println("-- listing properties --"); for (Map.Entry e : (Set)this.entrySet()){ String key = (String)e.getKey(); String val = (String)e.getValue(); if (val.length() > 40) { val = val.substring(0, 37) + "..."; } out.println(key + "=" + val); } } public Object put(Object key, Object value){ return linkMap.put(key, value); } public int size(){ return linkMap.size(); } public Collection values(){ return linkMap.values(); } //for test purpose only public static void main(String[] arg)throws Exception{ Properties p0=new Properties(); Properties p1=new LinkedProperties(); p0.put("aaa","111"); p0.put("bbb","222"); p0.put("ccc","333"); p0.put("ddd","444"); p1.put("aaa","111"); p1.put("bbb","222"); p1.put("ccc","333"); p1.put("ddd","444"); System.out.println("\n--"+p0.getClass()); p0.list(System.out); p0.store(System.out,"comments"); p0.storeToXML(System.out,"comments"); System.out.println(p0.toString()); System.out.println("\n--"+p1.getClass()); p1.list(System.out); p1.store(System.out,"comments"); p1.storeToXML(System.out,"comments"); System.out.println(p1.toString()); } } 

结果:

 --class java.util.Properties -- listing properties -- bbb=222 aaa=111 ddd=444 ccc=333 #comments #Wed Apr 10 08:55:42 EEST 2013 bbb=222 aaa=111 ddd=444 ccc=333    comments 222 111 444 333  {bbb=222, aaa=111, ddd=444, ccc=333} --class groovy.abi.LinkedProperties -- listing properties -- aaa=111 bbb=222 ccc=333 ddd=444 #comments #Wed Apr 10 08:55:42 EEST 2013 aaa=111 bbb=222 ccc=333 ddd=444    comments 111 222 333 444  {aaa=111, bbb=222, ccc=333, ddd=444} 

它们在引擎盖下被表示为Hashtable意味着它们的订单不以任何方式保存。

如果你非常渴望这个function,我建议你“推出自己的”属性读者。

正确实现keySet:

 public class OrderedProperties extends Properties { private Set keySet = new LinkedHashSet(100); @Override public Enumeration keys() { return Collections.enumeration(keySet); } @Override public Set keySet() { return keySet; } @Override public synchronized Object put(Object key, Object value) { if (! keySet.contains(key)) { keySet.add(key); } return super.put(key, value); } @Override public synchronized Object remove(Object key) { keySet.remove(key); return super.remove(key); } @Override public synchronized void putAll(Map values) { for (Object key : values.keySet()) { if (! containsKey(key)) { keySet.add(key); } } super.putAll(values); } } 

子类属性用于记忆阅读顺序并创建使用有序键列表的枚举?

解决问题:“根据属性文件中的顺序执行类。” 我通常使用以下两种可能之一:

1 – 使用一个属性作为逗号分隔列表,其中包含类名或类定义的键

loadClasses = class-definition-A,class-definition-B,class-definition-C

或(如果“定义”包含多个属性,则有用)

loadClasses = keyA,keyB,keyC
keyA = class-definition-A
keyB = class-definition-B
keyC = class-definition-C

2 – 使用键后跟索引(计数器)。 在循环中读取键,直到找不到值。

class1 = class-definition-A
class2 = class-definition-B
class3 = class-definition-C