Java Properties Beispiel lesen, schreiben und sortieren

Java properties File lesen, schreiben und sortieren

Java Properties

Jede komplexe Anwendung erfordert heutzutage irgendeine Art von Konfiguration. Manchmal müssen diese Konfigurationen schreibgeschützt sein (nur lesen) und manchmal müssen Konfigurationen geändert und abgespeichert werden können. Dieser Artikel soll zeigen, wie ein Konfigurationsmechanismus mittels Properties geladen, gelesen und geschrieben werden kann, um eine Java-Anwendungen einfach zu konfigurieren.

Schlüssel und ihre Werte

Die Eigenschaften werden im Key-Value Prinzip angegeben. Diese können mit unterschiedlichen Zeichen getrennt werden:

# Diese Zeile ist ein Kommentar
pi=3.14159265359
lang:deutsch

Weitere Beispiele werden hier beschrieben.

Laden und lesen der Properties-Datei

Im folgenden Beispiel wird mittels eines Singletons verhindert, dass bei jeder Schlüssel-Abfrage die Properties-Datei neu geladen wird. Stattdessen wird die Datei nur beim Starten ausgelesen und zwischengespeichert, da Input/Output-Operationen viel Zeit in Anspruch nehmen und für zeitkritische Anwendungen nicht verwendet werden können.

package at.blog.gridtec.handler;

import java.util.*;
import java.io.*;

public class PropertyHandler {

    private static PropertyHandler instance = null;
    private Properties prop = null;
    private static String propertiesFileName = "conf.properties";

    private PropertyHandler() {
        InputStream input = null;
        try {
            input = new FileInputStream(propertiesFileName);
            this.prop = new Properties();
            this.prop.load(input);
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public synchronized static PropertyHandler getInstance() {

        if (instance != null) {
            return instance;
        }
        synchronized (PropertyHandler.class) {
            if (instance == null) {
                instance = new PropertyHandler();
            }
        }
        return instance;
    }

    public String getValue(String propKey) {
        return this.prop.getProperty(propKey);
    }

    public Set<String> getAllPropertyNames() {
        return this.prop.stringPropertyNames();
    }

    public boolean containsKey(String key) {
        return this.prop.containsKey(key);
    }
}

Testen wir die Klasse:

public static void main(String[] args) {

    System.out.println(PropertyHandler.getInstance().containsKey("pi"));
    System.out.println(PropertyHandler.getInstance().getValue("pi"));
    System.out.println(PropertyHandler.getInstance().getValue("lang"));
    System.out.println(PropertyHandler.getInstance().getAllPropertyNames());
}

//Ausgabe:
//true
//3.14159265359
//deutsch
//[pi, lang]

 Speichern von geänderten Werten

Je nach Einsatzgebiet kann es durchaus Sinn machen, geänderte Properties abzuspeichern. Dazu wird folgende Methode zu der Klasse hinzugefügt:

public void saveParamChanges(String key, String value) {
    try {
        this.prop.setProperty(key, value);
        OutputStream out = new FileOutputStream(propertiesFileName);
        // Zeige letzte Änderungen als Kommentar im Properies File
        this.prop.store(out, "Last changes: " + key + "=" + value);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Probieren wir die neue Methode:

if (PropertyHandler.getInstance().containsKey("lang")) {
    PropertyHandler.getInstance().saveParamChanges("lang", "english");
}
if (PropertyHandler.getInstance().containsKey("pi")) {
    PropertyHandler.getInstance().saveParamChanges("pi", "0");
}

Sieht man sich nun die Properties-Datei an, sieht man folgendes:

#Last changes: pi=0
#Thu Apr 02 05:49:57 CEST 2015
pi=0
lang=english

Wie zu sehen ist, sind die einzelnen Properties nicht sortiert. Da dies, gerade bei größeren Properties-Dateien, von Vorteil wäre, wird die oben gezeigte PropertyHandler Klasse leicht modifiziert in dem eine Wrapper-Klasse instanziert wird.

Sortieren von Properties

Um die Properties sortiert in die Properties-Datei zu speichern, wird ein Wrapper für die Properties-Klasse benötigt:

package at.blog.gridtec.handler;

import java.util.Collections;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Vector;

class SortedProperties extends Properties {

    private static final long serialVersionUID = 4786733291853770802L;

    public Enumeration keys() {
        Enumeration keysEnum = super.keys();
        Vector<String> keyList = new Vector<String>();
        while (keysEnum.hasMoreElements()) {
            keyList.add((String) keysEnum.nextElement());
        }
        Collections.sort(keyList);
        return keyList.elements();
    }
}

Statt der Properties-Klasse muss nun die SortedProperties-Klasse instanziert werden. Ändert man jetzt einen Wert sieht die Properties-Datei so aus:

#Last changes: pi=0
#Thu Apr 02 06:55:31 CEST 2015
lang=english
pi=0

Abschließend noch einmal die komplette PropertiesHandler-Klasse:

package at.blog.gridtec.handler;

import java.util.*;
import java.io.*;

public class PropertyHandler {

    private static PropertyHandler instance = null;
    private SortedProperties prop = null;
    private static String PropertyFileName = "conf.properties";

    private PropertyHandler() {
        InputStream input = null;
        try {
            input = new FileInputStream(PropertyFileName);
            this.prop = new SortedProperties();
            this.prop.load(input);
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static synchronized PropertyHandler getInstance() {
        if (instance != null) {
            return instance;
        }
        synchronized (PropertyHandler.class) {

            if (instance == null) {
                instance = new PropertyHandler();
            }
        }
        return instance;
    }

    public String getValue(String propKey) {
        return this.prop.getProperty(propKey);
    }

    public Set<String> getAllPropertyNames() {
        return this.prop.stringPropertyNames();
    }

    public boolean containsKey(String key) {
        return this.prop.containsKey(key);
    }
}

 

 

Tagged with:     , ,

About the author /


Einst gelernter Werkzeugbautechniker, habe ich vor etlichen Jahren mein Leben der Informatik verschrieben. Zur Zeit studiere ich noch Informatik auf der Fachhochschule Technikum Wien und beschäftige mich am liebsten mit Java, Android und Elektronik.

Related Articles

Post your comments

Your email address will not be published. Required fields are marked *

*

Unterstütz uns!

Folgt uns!

Diese Seite

wurde erstellt mit Ehrgeiz, Liebe und viel Koffein. Bei der Erstellung kamen keine jar-Dateien zu Schaden. Das Logo wurde erstellt von Star-seven.at.