是否按顺序从Java Properties文件中提取值?

时间:2020-12-19 02:05:49

I have a properties file where the order of the values is important. I want to be able to iterate through the properties file and output the values based on the order of the original file.

我有一个属性文件,其中值的顺序很重要。我希望能够遍历属性文件并根据原始文件的顺序输出值。

However, since the Properties file is backed by, correct me if I'm wrong, a Map that does not maintain insertion order, the iterator returns the values in the wrong order.

但是,由于属性文件是后备的,如果我错了,请更正我,一个不保持插入顺序的Map,迭代器以错误的顺序返回值。

Here is the code I'm using

这是我正在使用的代码

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

Is there anyway to get the Properties back in order short of writting my own custom file parser?

反正有没有让我的自定义文件解析器写回来的属性?

14 个解决方案

#1


6  

If you can alter the property names your could prefix them with a numeral or other sortable prefix and then sort the Properties KeySet.

如果您可以更改属性名称,则可以使用数字或其他可排序前缀为它们添加前缀,然后对“属性”键设置进行排序。

#2


65  

Extend java.util.Properties, override both put() and keys():

扩展java.util.Properties,覆盖put()和keys():

import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Properties;
import java.util.HashMap;

public class LinkedProperties extends Properties {
    private final HashSet<Object> keys = new LinkedHashSet<Object>();

    public LinkedProperties() {
    }

    public Iterable<Object> orderedKeys() {
        return Collections.list(keys());
    }

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

    public Object put(Object key, Object value) {
        keys.add(key);
        return super.put(key, value);
    }
}

#3


10  

Nope - maps are inherently "unordered".

不 - 地图本质上是“无序的”。

You could possibly create your own subclass of Properties which overrode setProperty and possibly put, but it would probably get very implementation-specific... Properties is a prime example of bad encapsulation. When I last wrote an extended version (about 10 years ago!) it ended up being hideous and definitely sensitive to the implementation details of Properties.

您可以创建自己的属性子类,它可以覆盖setProperty并可能放置,但它可能会非常特定于实现...属性是错误封装的主要示例。当我上次写一个扩展版本(大约10年前!)时,它最终变得丑陋,对于Properties的实现细节肯定很敏感。

#4


5  

Dominique Laurent's solution above works great for me. I also added the following method override:

Dominique Laurent的解决方案对我来说非常有用。我还添加了以下方法覆盖:

public Set<String> stringPropertyNames() {
    Set<String> set = new LinkedHashSet<String>();

    for (Object key : this.keys) {
        set.add((String)key);
    }

    return set;
}

Probably not the most efficient, but it's only executed once in my servlet lifecycle.

可能不是最有效的,但它只在我的servlet生命周期中执行一次。

Thanks Dominique!

#5


3  

Apache Commons Configuration might do the trick for you. I haven't tested this myself, but I checked their sources and looks like property keys are backed by LinkedList in AbstractFileConfiguration class:

Apache Commons Configuration可能会为您提供帮助。我自己没有测试过这个,但是我查看了它们的源代码,看起来属性键是由AbstractFileConfiguration类中的LinkedList支持的:

public Iterator getKeys()
{
    reload();
    List keyList = new LinkedList();
    enterNoReload();
    try
    {
        for (Iterator it = super.getKeys(); it.hasNext();)
        {
            keyList.add(it.next());
        }

        return keyList.iterator();
    }
    finally
    {
        exitNoReload();
    }
}

#6


2  

In the interest of completeness ...

为了完整......

public class LinkedProperties extends Properties {

    private final LinkedHashSet<Object> keys = new LinkedHashSet<Object>();

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

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

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

    public Object put(Object key, Object value) {
        keys.add(key);
        return super.put(key, value);
    }

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

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

I dont think the methods returning set should be overridden as a set by definition does not maintain insertion order

我不认为返回集的方法应该被覆盖,因为定义的集合不维护插入顺序

#7


2  

Map<String, String> mapFile = new LinkedHashMap<String, String>();
ResourceBundle bundle = ResourceBundle.getBundle(fileName);
TreeSet<String> keySet = new TreeSet<String>(bundle.keySet());
for(String key : keySet){
    System.out.println(key+" "+bundle.getString(key));
    mapFile.put(key, bundle.getString(key));
}

This persist the order of property file

这会持久保存属性文件的顺序

#8


2  

Working example :

工作范例:

Map<String,String> properties = getOrderedProperties(new FileInputStream(new File("./a.properties")));
properties.entrySet().forEach(System.out::println);

Code for it

它的代码

public Map<String, String> getOrderedProperties(InputStream in) throws IOException{
    Map<String, String> mp = new LinkedHashMap<>();
    (new Properties(){
        public synchronized Object put(Object key, Object value) {
            return mp.put((String) key, (String) value);
        }
    }).load(in);
    return mp;
}

#9


1  

You must override also keySet() if you want to export Properties as XML:

如果要将Properties导出为XML,则还必须覆盖keySet():

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

public Set keySet(){返回键; }

#10


1  

See https://github.com/etiennestuder/java-ordered-properties for a complete implementation that allows to read/write properties files in a well-defined order.

有关完整实现的信息,请参阅https://github.com/etiennestuder/java-ordered-properties,该实现允许以明确定义的顺序读/写属性文件。

OrderedProperties properties = new OrderedProperties();
properties.load(new FileInputStream(new File("~/some.properties")));

#11


1  

I'll add one more famous YAEOOJP (Yet Another Example Of Ordered Java Properties) to this thread because it seems nobody could ever care less about default properties which you can feed to your properties.

我将添加一个着名的YAEOOJP(有序Java属性的另一个例子)到这个线程,因为似乎没有人会关心你可以提供给你的属性的默认属性。

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

That's my class: surely not 1016% compliant with any possible situation, but that is fine for my limited dumb purposes right now. Any further comment for correction is appreciated so the Greater Good can benefit.

这是我的班级:肯定不是1016%符合任何可能的情况,但这对我目前有限的愚蠢目的来说是好的。任何进一步的更正评论都表示赞赏,因此大善可以受益。

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

#12


1  

As I see it, Properties is to much bound to Hashtable. I suggest reading it in order to a LinkedHashMap. For that you'll only need to override a single method, Object put(Object key, Object value), disregarding the Properties as a key/value container:

正如我所看到的,属性与Hashtable有很大关系。我建议读一下LinkedHashMap。为此,您只需要覆盖单个方法,Object put(Object key,Object value),忽略Properties作为键/值容器:

public class InOrderPropertiesLoader<T extends Map<String, String>> {

    private final T map;

    private final Properties properties = new Properties() {
        public Object put(Object key, Object value) {
            map.put((String) key, (String) value);
            return null;
        }

    };

    public InOrderPropertiesLoader(T map) {
        this.map = map;
    }

    public synchronized T load(InputStream inStream) throws IOException {
        properties.load(inStream);

        return map;
    }
}

Usage:

LinkedHashMap<String, String> props = new LinkedHashMap<>();
try (InputStream inputStream = new FileInputStream(file)) {
    new InOrderPropertiesLoader<>(props).load(inputStream);
}

#13


1  

In some answers it is assumed that properties read from file are put to instance of Properties (by calls to put) in order they appear they in file. While this is in general how it behaves I don't see any guarantee for such order.

在某些答案中,假设从文件读取的属性被放置到Properties的实例(通过调用put),以便它们出现在文件中。虽然这是一般的行为方式,但我没有看到任何此类订单的保证。

IMHO: it is better to read the file line by line (so that the order is guaranteed), than use the Properties class just as a parser of single property line and finally store it in some ordered Collection like LinkedHashMap.

恕我直言:最好逐行读取文件(以保证顺序),而不是使用Properties类作为单个属性行的解析器,最后将它存储在一些有序的Collection中,如LinkedHashMap。

This can be achieved like this:

这可以这样实现:

private LinkedHashMap<String, String> readPropertiesInOrderFrom(InputStream propertiesFileInputStream)
                                                           throws IOException {
    if (propertiesFileInputStream == null) {
      return new LinkedHashMap(0);
    }

    LinkedHashMap<String, String> orderedProperties = new LinkedHashMap<String, String>();

    final Properties properties = new Properties(); // use only as a parser
    final BufferedReader reader = new BufferedReader(new InputStreamReader(propertiesFileInputStream));

    String rawLine = reader.readLine();

    while (rawLine != null) {
      final ByteArrayInputStream lineStream = new ByteArrayInputStream(rawLine.getBytes("ISO-8859-1"));
      properties.load(lineStream); // load only one line, so there is no problem with mixing the order in which "put" method is called


      final Enumeration<?> propertyNames = properties.<String>propertyNames();

      if (propertyNames.hasMoreElements()) { // need to check because there can be empty or not parsable line for example

        final String parsedKey = (String) propertyNames.nextElement();
        final String parsedValue = properties.getProperty(parsedKey);

        orderedProperties.put(parsedKey, parsedValue);
        properties.clear(); // make sure next iteration of while loop does not access current property
      }

      rawLine = reader.readLine();
    }

    return orderedProperties;

  }

Just note that the method posted above takes an InputStream which should be closed afterwards (of course there is no problem to rewrite it to take just a file as an argument).

请注意,上面发布的方法需要一个应该在之后关闭的InputStream(当然,重写它只需要一个文件作为参数就没有问题)。

#14


-1  

An alternative is just to write your own properties file using LinkedHashMap, here is what I use :

另一种方法是使用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);
    }

}

To use :

使用:

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

Sample properties file (in this case project.properties) :

示例属性文件(在本例中为project.properties):

test=test2

#1


6  

If you can alter the property names your could prefix them with a numeral or other sortable prefix and then sort the Properties KeySet.

如果您可以更改属性名称,则可以使用数字或其他可排序前缀为它们添加前缀,然后对“属性”键设置进行排序。

#2


65  

Extend java.util.Properties, override both put() and keys():

扩展java.util.Properties,覆盖put()和keys():

import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Properties;
import java.util.HashMap;

public class LinkedProperties extends Properties {
    private final HashSet<Object> keys = new LinkedHashSet<Object>();

    public LinkedProperties() {
    }

    public Iterable<Object> orderedKeys() {
        return Collections.list(keys());
    }

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

    public Object put(Object key, Object value) {
        keys.add(key);
        return super.put(key, value);
    }
}

#3


10  

Nope - maps are inherently "unordered".

不 - 地图本质上是“无序的”。

You could possibly create your own subclass of Properties which overrode setProperty and possibly put, but it would probably get very implementation-specific... Properties is a prime example of bad encapsulation. When I last wrote an extended version (about 10 years ago!) it ended up being hideous and definitely sensitive to the implementation details of Properties.

您可以创建自己的属性子类,它可以覆盖setProperty并可能放置,但它可能会非常特定于实现...属性是错误封装的主要示例。当我上次写一个扩展版本(大约10年前!)时,它最终变得丑陋,对于Properties的实现细节肯定很敏感。

#4


5  

Dominique Laurent's solution above works great for me. I also added the following method override:

Dominique Laurent的解决方案对我来说非常有用。我还添加了以下方法覆盖:

public Set<String> stringPropertyNames() {
    Set<String> set = new LinkedHashSet<String>();

    for (Object key : this.keys) {
        set.add((String)key);
    }

    return set;
}

Probably not the most efficient, but it's only executed once in my servlet lifecycle.

可能不是最有效的,但它只在我的servlet生命周期中执行一次。

Thanks Dominique!

#5


3  

Apache Commons Configuration might do the trick for you. I haven't tested this myself, but I checked their sources and looks like property keys are backed by LinkedList in AbstractFileConfiguration class:

Apache Commons Configuration可能会为您提供帮助。我自己没有测试过这个,但是我查看了它们的源代码,看起来属性键是由AbstractFileConfiguration类中的LinkedList支持的:

public Iterator getKeys()
{
    reload();
    List keyList = new LinkedList();
    enterNoReload();
    try
    {
        for (Iterator it = super.getKeys(); it.hasNext();)
        {
            keyList.add(it.next());
        }

        return keyList.iterator();
    }
    finally
    {
        exitNoReload();
    }
}

#6


2  

In the interest of completeness ...

为了完整......

public class LinkedProperties extends Properties {

    private final LinkedHashSet<Object> keys = new LinkedHashSet<Object>();

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

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

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

    public Object put(Object key, Object value) {
        keys.add(key);
        return super.put(key, value);
    }

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

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

I dont think the methods returning set should be overridden as a set by definition does not maintain insertion order

我不认为返回集的方法应该被覆盖,因为定义的集合不维护插入顺序

#7


2  

Map<String, String> mapFile = new LinkedHashMap<String, String>();
ResourceBundle bundle = ResourceBundle.getBundle(fileName);
TreeSet<String> keySet = new TreeSet<String>(bundle.keySet());
for(String key : keySet){
    System.out.println(key+" "+bundle.getString(key));
    mapFile.put(key, bundle.getString(key));
}

This persist the order of property file

这会持久保存属性文件的顺序

#8


2  

Working example :

工作范例:

Map<String,String> properties = getOrderedProperties(new FileInputStream(new File("./a.properties")));
properties.entrySet().forEach(System.out::println);

Code for it

它的代码

public Map<String, String> getOrderedProperties(InputStream in) throws IOException{
    Map<String, String> mp = new LinkedHashMap<>();
    (new Properties(){
        public synchronized Object put(Object key, Object value) {
            return mp.put((String) key, (String) value);
        }
    }).load(in);
    return mp;
}

#9


1  

You must override also keySet() if you want to export Properties as XML:

如果要将Properties导出为XML,则还必须覆盖keySet():

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

public Set keySet(){返回键; }

#10


1  

See https://github.com/etiennestuder/java-ordered-properties for a complete implementation that allows to read/write properties files in a well-defined order.

有关完整实现的信息,请参阅https://github.com/etiennestuder/java-ordered-properties,该实现允许以明确定义的顺序读/写属性文件。

OrderedProperties properties = new OrderedProperties();
properties.load(new FileInputStream(new File("~/some.properties")));

#11


1  

I'll add one more famous YAEOOJP (Yet Another Example Of Ordered Java Properties) to this thread because it seems nobody could ever care less about default properties which you can feed to your properties.

我将添加一个着名的YAEOOJP(有序Java属性的另一个例子)到这个线程,因为似乎没有人会关心你可以提供给你的属性的默认属性。

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

That's my class: surely not 1016% compliant with any possible situation, but that is fine for my limited dumb purposes right now. Any further comment for correction is appreciated so the Greater Good can benefit.

这是我的班级:肯定不是1016%符合任何可能的情况,但这对我目前有限的愚蠢目的来说是好的。任何进一步的更正评论都表示赞赏,因此大善可以受益。

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

#12


1  

As I see it, Properties is to much bound to Hashtable. I suggest reading it in order to a LinkedHashMap. For that you'll only need to override a single method, Object put(Object key, Object value), disregarding the Properties as a key/value container:

正如我所看到的,属性与Hashtable有很大关系。我建议读一下LinkedHashMap。为此,您只需要覆盖单个方法,Object put(Object key,Object value),忽略Properties作为键/值容器:

public class InOrderPropertiesLoader<T extends Map<String, String>> {

    private final T map;

    private final Properties properties = new Properties() {
        public Object put(Object key, Object value) {
            map.put((String) key, (String) value);
            return null;
        }

    };

    public InOrderPropertiesLoader(T map) {
        this.map = map;
    }

    public synchronized T load(InputStream inStream) throws IOException {
        properties.load(inStream);

        return map;
    }
}

Usage:

LinkedHashMap<String, String> props = new LinkedHashMap<>();
try (InputStream inputStream = new FileInputStream(file)) {
    new InOrderPropertiesLoader<>(props).load(inputStream);
}

#13


1  

In some answers it is assumed that properties read from file are put to instance of Properties (by calls to put) in order they appear they in file. While this is in general how it behaves I don't see any guarantee for such order.

在某些答案中,假设从文件读取的属性被放置到Properties的实例(通过调用put),以便它们出现在文件中。虽然这是一般的行为方式,但我没有看到任何此类订单的保证。

IMHO: it is better to read the file line by line (so that the order is guaranteed), than use the Properties class just as a parser of single property line and finally store it in some ordered Collection like LinkedHashMap.

恕我直言:最好逐行读取文件(以保证顺序),而不是使用Properties类作为单个属性行的解析器,最后将它存储在一些有序的Collection中,如LinkedHashMap。

This can be achieved like this:

这可以这样实现:

private LinkedHashMap<String, String> readPropertiesInOrderFrom(InputStream propertiesFileInputStream)
                                                           throws IOException {
    if (propertiesFileInputStream == null) {
      return new LinkedHashMap(0);
    }

    LinkedHashMap<String, String> orderedProperties = new LinkedHashMap<String, String>();

    final Properties properties = new Properties(); // use only as a parser
    final BufferedReader reader = new BufferedReader(new InputStreamReader(propertiesFileInputStream));

    String rawLine = reader.readLine();

    while (rawLine != null) {
      final ByteArrayInputStream lineStream = new ByteArrayInputStream(rawLine.getBytes("ISO-8859-1"));
      properties.load(lineStream); // load only one line, so there is no problem with mixing the order in which "put" method is called


      final Enumeration<?> propertyNames = properties.<String>propertyNames();

      if (propertyNames.hasMoreElements()) { // need to check because there can be empty or not parsable line for example

        final String parsedKey = (String) propertyNames.nextElement();
        final String parsedValue = properties.getProperty(parsedKey);

        orderedProperties.put(parsedKey, parsedValue);
        properties.clear(); // make sure next iteration of while loop does not access current property
      }

      rawLine = reader.readLine();
    }

    return orderedProperties;

  }

Just note that the method posted above takes an InputStream which should be closed afterwards (of course there is no problem to rewrite it to take just a file as an argument).

请注意,上面发布的方法需要一个应该在之后关闭的InputStream(当然,重写它只需要一个文件作为参数就没有问题)。

#14


-1  

An alternative is just to write your own properties file using LinkedHashMap, here is what I use :

另一种方法是使用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);
    }

}

To use :

使用:

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

Sample properties file (in this case project.properties) :

示例属性文件(在本例中为project.properties):

test=test2