16 votes

Comment lire un fichier de propriétés en java dans l'ordre original

J'ai besoin de lire un fichier de propriétés et générer un Propriétés en Java. Je le fais en utilisant :

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

Cependant, les propriétés renvoyées par props.propertyName ne sont pas dans l'ordre du fichier de propriétés original. Je comprends que Propriétés ne sont que des tableaux de hashs, non générés, à l'ancienne. Je cherche une solution de contournement. Une idée ? Merci !

18voto

YoK Points 8221

Exemple de www.java2s.com devrait résoudre votre problème.

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;

}

Et votre code sera changé en :

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

13voto

Sean Patrick Floyd Points 109428

Vous pouvez étendre les propriétés et déléguer toutes les méthodes d'indexation à un fichier de type Cartouche de hachage pour conserver l'ordre. Voici un exemple (vous devrez peut-être modifier d'autres méthodes) :

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);
    }

}

8voto

Wayne Johnson Points 71

Similaire à l'une des solutions ci-dessus, mais sans les frais généraux de maintien de notre propre liste de valeurs. Tout ce que nous avons à faire est de maintenir une liste ordonnée séparée des clés, et de fournir une nouvelle méthode "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);
    }
}

6voto

pavanlimo Points 1921

Vous pouvez implémenter votre propre classe de propriétés avec des fonctionnalités similaires. Il ne vous sera pas possible d'obtenir la commande puisque, comme vous l'avez déjà souligné, elle utilise Hashtable .

3voto

daggett Points 61

Implémentation complète basée sur 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());
    }
}

Résultat :

--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}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X