Вопрос по properties, java, enumeration – Как прочитать файл свойств в Java в оригинальном порядке [дубликата]

14

На этот вопрос уже есть ответ здесь:

Вытащить значения из файла свойств Java в порядке?14 ответов

Мне нужно прочитать файл свойств и сгенерироватьсвойства класс на Java. Я делаю это с помощью:

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

Однако свойства, возвращаемые props.propertyName, не соответствуют порядку исходного файла свойств. Я это понимаюсвойства это просто старомодные, непроизведенные Hashtables. Я ищу работу вокруг. Любая идея? Спасибо!

Мне нужно выполнить классы на основе порядка в файле свойств. wen
+1 спасибо, что задали мне этот вопрос, у меня точно такая же проблема! :) samsamara
Это на самом деле обобщается, какHashtable<Object,Object> (возникает вопрос, почему это где-то). Tom Hawtin - tackline
public Map <Object, Object> getOrderedProperties (InputStream in) генерирует IOException {Map <Object, Object> mp = new LinkedHashMap <> (); (new Properties () {публичный синхронизированный объект put (ключ объекта, значение объекта) {return mp.put (ключ, значение);}}). load (in); возврат mp; } Dharmendrasinh Chudasama
Любая конкретная причина, по которой порядок имеет значение? Powerlord

Ваш Ответ

9   ответов
13

Вы можете расширить Свойства и делегировать все методы карты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);
    }

}
Мне просто нужно переопределить больше из них :-), но спасибо за вдохновение To Kra
@ ToKra, очевидно, да. Спасибо Sean Patrick Floyd
Красиво и просто. Можно упростить, сохранив значения в обоихsuper иlinkMap и тогда может только переопределить операции модификации и типа итерации. напримерput {connectedMap.put (ключ, значение); вернуть super.put (ключ, значение); } karmakaze
Я бы предложил@Override такжеsize() а такжеtoString() To Kra
0

Свойства подкласса, чтобы запомнить порядок чтения и создать Перечисление, которое использует список упорядоченных ключей?

0

Для решения проблемы: «выполнять классы по порядку в файле свойств». Я обычно использовал одну из 2 возможностей:

1 - использовать одно свойство в виде списка через запятую с именами классов или ключами к определению класса

loadClasses = определение-класса-A, определение-класса-B, определение-класса-C

или (полезно, если «определение» состоит из более чем одного свойства)

loadClasses = keyA, keyB, keyC
keyA = определение класса-A
ключ B = определение класса-B
keyC = определение класса-C


2 - используйте ключ, за которым следует индекс (счетчик). Читайте ключи в цикле, пока не будет найдено значение.

класс1 = определение класса-A
класс2 = определение класса-B
class3 = определение класса-C

7

Аналогично одному из вышеперечисленных, но не требует дополнительных затрат на ведение собственного списка значений. Все, что нам нужно сделать, это поддерживать отдельный упорядоченный список ключей и предоставить новый метод "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);
    }
}
Как насчет того, чтобы использоватьLinkedHashSet и избегать всех техcontainsKey ? Campa
3

полная реализация на основе 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());
    }
}

Результат:

--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}
только это сработало для меня. Это действительно прочитало файлы свойств в фактических последовательностях. linuxeasy
2

Тот факт, что они представлены какHashtable Под капотом подразумевается, что их порядок не держится никак.

Я бы посоветовал вам «свернуть свой собственный» ридер свойств, если вы абсолютно отчаянно нуждаетесь в этой функции.

Там нет ничего "под капотом" об использованииHashtable - Properties extends Hashtable<Object,Object>. Tom Hawtin - tackline
17

Пример из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;

}

И ваш код изменится на:

Properties props = new OrderedProperties();
props.load(new FileInputStream(args[0]));
for (Enumeration e = props.propertyNames(); e.hasMoreElements();) {
}
@broiyan Это решение должно работать независимо от того, как создается файл свойств. YoK
Возможно, вы захотите учесть, что вопрос можно интерпретировать как означающий, что мы хотим прочитать оригинальный файл, который не был создан программно или не создан с помощью вашего класса OrderedProperties. В таких случаях предлагаемое решение не является решением. H2ONaCl
Это работает как шарм. Я использовал его следующим образом: Properties properties = new OrderedProperties (); Map <String, String> propertyFileMap = new LinkedHashMap <> (); Перечисление <String> propertyKeyNames = (Перечисление <String>) properties.propertyNames (); while (propertyKeyNames.hasMoreElements ()) {String propertyKey = propertyKeyNames.nextElement (); String propertyValue = properties.getProperty (propertyKey); propertyFileMap.put (propertyKey, propertyValue); } Rahul Saini
Это OrderedProperties расширяет свойства должны быть принятым ответом !! Rahul Saini
2

Правильная реализация набора ключей:

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);
  }
}
Здравствуйте! Содержимое () было бы неплохо добавить. Страшную кириллицу заменить естественным английским :) GKislin
ИХМО.contains() звонить здесь совсем неактуально, верно? PS для нерусских читателей: та страшная кириллицаправильной реализацией означает «правильная реализация»! Campa
Почемуload методы не переопределены? Stephan
6

Возможно, вы захотите реализовать свой собственный класс Properties с аналогичными функциями. Вы не сможете получить заказ, поскольку, как вы уже указали, он используетHashtable.

Похожие вопросы