Вытащить значения из файла свойств Java по порядку? - PullRequest
30 голосов
/ 21 августа 2009

У меня есть файл свойств, в котором важен порядок значений. Я хочу иметь возможность перебирать файл свойств и выводить значения в соответствии с порядком исходного файла.

Однако, так как файл свойств поддерживается, поправьте меня, если я ошибаюсь, карту, которая не поддерживает порядок вставки, итератор возвращает значения в неправильном порядке .

Вот код, который я использую

Enumeration names = propfile.propertyNames();
while (names.hasMoreElements()) {
    String name = (String) names.nextElement();
    //do stuff
}

Есть ли способ вернуть свойства обратно, если бы я не написал свой собственный анализатор файлов?

Ответы [ 14 ]

2 голосов
/ 17 апреля 2015

Я добавлю еще один известный YAEOOJP ( Еще один пример упорядоченных свойств Java ) в этот поток, потому что кажется, что никто никогда не будет заботиться о стандартных свойствах, которые вы можете передать в вашу собственность.

@ см. http://docs.oracle.com/javase/tutorial/essential/environment/properties.html

Это мой класс: конечно, 10 16 % не соответствует любой возможной ситуации, но сейчас это хорошо для моих ограниченных тупых целей. Любые дальнейшие комментарии для исправления приветствуются, поэтому Великое Благо может принести пользу.

import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
 * Remember javadocs  >:o
 */
public class LinkedProperties extends Properties {

    protected LinkedProperties linkedDefaults;
    protected Set<Object> linkedKeys = new LinkedHashSet<>();

    public LinkedProperties() { super(); }

    public LinkedProperties(LinkedProperties defaultProps) {
        super(defaultProps); // super.defaults = defaultProps;
        this.linkedDefaults = defaultProps;
    }

    @Override
    public synchronized Enumeration<?> propertyNames() {
        return keys();
    }

    @Override
    public Enumeration<Object> keys() {
        Set<Object> allKeys = new LinkedHashSet<>();
        if (null != defaults) {
            allKeys.addAll(linkedDefaults.linkedKeys);
        }
        allKeys.addAll(this.linkedKeys);
        return Collections.enumeration(allKeys);
    }

    @Override
    public synchronized Object put(Object key, Object value) {
        linkedKeys.add(key);
        return super.put(key, value);
    }

    @Override
    public synchronized Object remove(Object key) {
        linkedKeys.remove(key);
        return super.remove(key);
    }

    @Override
    public synchronized void putAll(Map<?, ?> values) {
        for (Object key : values.keySet()) {
            linkedKeys.add(key);
        }
        super.putAll(values);
    }

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

    private static final long serialVersionUID = 0xC00L;
}
2 голосов
/ 12 декабря 2014

См. https://github.com/etiennestuder/java-ordered-properties для полной реализации, которая позволяет читать / записывать файлы свойств в четко определенном порядке.

OrderedProperties properties = new OrderedProperties();
properties.load(new FileInputStream(new File("~/some.properties")));
2 голосов
/ 19 августа 2010

Вы также должны переопределить keySet (), если хотите экспортировать свойства в формате XML:

public Set<Object> keySet() { return keys; }

0 голосов
/ 18 декабря 2013

Альтернативой является просто написать собственный файл свойств с помощью LinkedHashMap, вот что я использую:

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.LineIterator;

public class OrderedProperties {

    private static Map<String, String> properties = new LinkedHashMap<String, String>();

    private static OrderedProperties instance = null;

    private OrderedProperties() {

    }

    //The propertyFileName is read from the classpath and should be of format : key=value
    public static synchronized OrderedProperties getInstance(String propertyFileName) {
        if (instance == null) {
            instance = new OrderedProperties();
            readPropertiesFile(propertyFileName);
        }
        return instance;
    }

    private static void readPropertiesFile(String propertyFileName){
        LineIterator lineIterator = null;
        try {

            //read file from classpath
            URL url = instance.getClass().getResource(propertyFileName);

            lineIterator = FileUtils.lineIterator(new File(url.getFile()), "UTF-8");
            while (lineIterator.hasNext()) {
                String line = lineIterator.nextLine();

                //Continue to parse if there are blank lines (prevents IndesOutOfBoundsException)
                if (!line.trim().isEmpty()) {
                    List<String> keyValuesPairs = Arrays.asList(line.split("="));
                    properties.put(keyValuesPairs.get(0) , keyValuesPairs.get(1));
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            lineIterator.close();
        }
    }

    public Map<String, String> getProperties() {
        return OrderedProperties.properties;
    }

    public String getProperty(String key) {
        return OrderedProperties.properties.get(key);
    }

}

Для использования:

    OrderedProperties o = OrderedProperties.getInstance("/project.properties");
    System.out.println(o.getProperty("test"));

Пример файла свойств (в данном случае project.properties):

test=test2
...