Pulling values from a Java Properties file in order?

前端 未结 15 652
庸人自扰
庸人自扰 2020-12-02 18:32

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

相关标签:
15条回答
  • 2020-12-02 19:01

    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.

    0 讨论(0)
  • 2020-12-02 19:02

    For those who read this topic recently: just use class PropertiesConfiguration from org.apache.commons:commons-configuration2. I've tested that it keeps properties ordering (because it uses LinkedHashMap internally). Doing:

    `
        PropertiesConfiguration properties = new PropertiesConfiguration();
        properties.read(new FileReader("/some/path));
        properties.write(new FileWriter("/some/other/path"));
    `
    

    only removes trailing whitespace and unnecessary escapes.

    0 讨论(0)
  • 2020-12-02 19:09

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

    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) :

    test=test2
    
    0 讨论(0)
  • 2020-12-02 19:11

    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:

    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);
    }
    
    0 讨论(0)
  • 2020-12-02 19:12

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

    0 讨论(0)
  • 2020-12-02 19:13
    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

    0 讨论(0)
提交回复
热议问题