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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3619796/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 02:46:12  来源:igfitidea点击:

How to read a properties file in java in the original order

javapropertiesenumeration

提问by wen

I need to read a properties file and generate a Propertiesclass in Java. I do so by using:

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

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

However, the properties returned by props.propertyName is not in the order of the original properties file. I understand that Propertiesare just old fashioned, non-generified Hashtables. I'm looking for a work around. Any idea? Thank you!

但是 props.propertyName 返回的属性并没有按照原始属性文件的顺序。我知道属性只是老式的、非通用的哈希表。我正在寻找解决办法。任何的想法?谢谢!

采纳答案by pavanlimo

You may want to implement your own Properties class with similar functionalities. It will not be possible for you to obtain the order since, as you already pointed out, it uses Hashtable.

您可能希望实现自己的具有类似功能的 Properties 类。您将无法获得订单,因为正如您已经指出的那样,它使用Hashtable.

回答by Noel M

The fact they are represented as a Hashtableunder the hood means that their order is not kept in any fashion.

它们被表示为Hashtable引擎盖下的事实意味着它们的顺序没有以任何方式保持。

I'd suggest you "roll your own" properties reader if you're absolutely desperate for this functionality.

如果您绝对需要此功能,我建议您“推出自己的”属性阅读器。

回答by Riduidel

Subclass Properties to memorize reading order and create an Enumeration that uses the ordered keys list ?

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

回答by Sean Patrick Floyd

You can extend Properties and delegate all map methods to a LinkedHashMapto retain the order. Here is an example (you may need to override some more methods):

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

public class LinkedProperties extends Properties{


    private static final long serialVersionUID = 1L;

    private Map<Object, Object> linkMap = new LinkedHashMap<Object,Object>();

    @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<Object> elements(){
        throw new UnsupportedOperationException(
          "Enumerations are so old-school, don't use them, "
        + "use keySet() or entrySet() instead");
    }

    @Override
    public Set<Entry<Object, Object>> entrySet(){
        return linkMap.entrySet();
    }

    @Override
    public synchronized void clear(){
        linkMap.clear();
    }

    @Override
    public synchronized boolean containsKey(Object key){
        return linkMap.containsKey(key);
    }

}

回答by YoK

Example from www.java2s.comshould solve your problem.

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

import java.util.Enumeration;
import java.util.Properties;
import java.util.Vector;

/**
 * <a href="OrderedProperties.java.html"><b><i>View Source</i></b></a>
 *
 * @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;

}

And your code will change to:

您的代码将更改为:

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

回答by user85421

To solve the problem: "to execute classes based on the order in the properties file." I normally used one of 2 possibilities:

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

1 - use one property as a comma-separated list with the class-names or with the keys to the class definition

1 - 使用一个属性作为带有类名或类定义键的逗号分隔列表

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

loadClasses = 类定义-A、类定义-B、类定义-C

or (useful if the "definition" consists of more than one property)

或(如果“定义”由多个属性组成,则很有用)

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

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


2 - use a key followed by an index (counter). Read the keys in a loop until no value is found.


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

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

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

回答by Wayne Johnson

Similar to one of the above, but w/out the overhead of maintaining our own list of values. All we have to do is maintain a separate ordered list of the keys, and provide a new "keys()" method.

类似于上述之一,但没有维护我们自己的值列表的开销。我们所要做的就是维护一个单独的有序键列表,并提供一个新的“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);
    }
}

回答by Grigory Kislin

Proper implementation of keySet:

keySet 的正确实现:

public class OrderedProperties extends Properties {

  private Set<Object> keySet = new LinkedHashSet<Object>(100);

  @Override
  public Enumeration<Object> keys() {
    return Collections.enumeration(keySet);
  }

  @Override
  public Set<Object> 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);
  }
}

回答by daggett

full implementation based on LinkedHashMap

基于 LinkedHashMap 的完整实现

import java.util.*;
import java.io.*;

/**
 * Ordered properties implementation
*/

public class LinkedProperties extends Properties{
    private static final long serialVersionUID = 1L;

    private Map<Object, Object> linkMap = new LinkedHashMap<Object,Object>();

    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<Map.Entry>)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());
    }
}

Result:

结果:

--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
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>comments</comment>
<entry key="bbb">222</entry>
<entry key="aaa">111</entry>
<entry key="ddd">444</entry>
<entry key="ccc">333</entry>
</properties>
{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
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>comments</comment>
<entry key="aaa">111</entry>
<entry key="bbb">222</entry>
<entry key="ccc">333</entry>
<entry key="ddd">444</entry>
</properties>
{aaa=111, bbb=222, ccc=333, ddd=444}