View RSS Feed

Java Basic

How to use properties file in Java

Rate this Entry
by , 02-29-2012 at 09:57 AM (41442 Views)
Software programs may need to store its settings or configuration in a file on disk, such as database connection settings or user preferences. In Java, it is possible to use some classes in the java.io package such as FileReader and FileWriter to read/write the configuration file. However, that approach is tedious and error-prone, because it requires writing a lot of code from scratch. Fortunately, the Java platform provides an out-of-the-box utility class which is designed specifically for that purpose. It is the Properties class in the java.util package. We will learn how to apply the API to write a utility class that encapsulates the load/save, read/write of configuration settings from/to a file. Then the utility class can be re-used in applications that need loading/saving settings from files on disk.

Java API for properties file

The Properties.java class resides in the package java.util and is available since JDK 1.0. It stores a set of properties in form of key/value pairs in a property list, that’s why it extends from Hashtable class. The properties can be loaded from a file or saved to a file. It can work with two types of file format:

  • *.properties file: this format is simple line-oriented, each key/value pair is store in one line. For example:
    Plain Code: A sample properties file generated by Properties class
    #My Application Settings
    
    #Sat Feb 25 10:25:06 ICT 2012
    
    port=5432
    
    user=postgres
    
    host=192.168.1.1
    
    pass=sergtsop
  • *.xml file: this is standard XML format. For example:
    XML Code: A sample XML file generated by Properties class
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    
    <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
    
    <properties>
    
    <comment>My Application Settings</comment>
    
    <entry key="port">955</entry>
    
    <entry key="user">admin</entry>
    
    <entry key="host">183.152.181.1</entry>
    
    <entry key="pass">nimda</entry>
    
    </properties>



The class has two constructors:

  • Properties(): this empty constructor creates an empty property list.
  • Properties(Properties defaults): this constructor creates an empty property list with the specified default. Default is a second property list which will be used if a key is not found in the original list.



The following methods can be used to load properties from a file:

  • load(InputStream inputStream): reads a property list from an input stream of a text file. Default encoding is ISO 8859-1.
  • load(Reader reader): reads a property list from a character stream.
  • loadFromXML(InputStream in): reads a property list from an XML file.


The following methods can be used to save properties to a file:

  • store(OutputStream out, String comments): writes the property list to an output stream of text file.
  • store(Writer writer, String comments): writes the property list to a character stream of text file.
  • storeToXML(OutputStream out, String comment): writes the property list to an XML file with default encoding is UTF-8.
  • storeToXML(OutputStream out, String comment, String encoding): write the property list to an XML file with the specified encoding.


The following methods can be used to read value of a property:

  • getProperty(String key): searches for a property with the specified key, returns null if the key is not found.
  • getProperty(String key, String defaultValue): returns value of a property specified by the key, or returns the defaultValue if the key is not found.



And this method sets value for a property:

  • setProperty(String key, String value): put a property with the specified key and value into the property list.


The Properties class is thread-safe, that means you don’t have to write synchronization code when an object of this class is being used by multiple threads.


Load properties file

The following code loads a property list from a text file into the Properties object:

Java Code: Load a properties file
String configFilePath = “D:/settings.properties”;
Properties properties = new Properties();
FileInputStream  fis = new FileInputStream(configFilePath);
properties.load(fis);
Note that we should close the input stream after loading:

Java Code: Close the input stream
            if (fis != null) {
                fis.close();
            }

Reading properties

Once the Properties object is loaded with a property list from file, we can use the getProperty() methods to retrieve the values of the properties defined in the file:

Java Code: Retrieve value of a property
String hostname = properties.getProperty(“host”);
If we want to return the default value for a property if it is not present, use the second version of the method:

Java Code: Retrieve value of a property, or return a default value if not found
String hostname = properties.getProperty(“host”, “localhost”);

Setting properties

Updating value for a property is straight forward:

Java Code: Set value for a property
properties.setProperty(“host”, “192.168.1.1”);
Note that the property’s value is not updated in the underlying file until we call the store() methods.


Saving properties file

The following code stores the property list of the Properties object to the underlying file:

Java Code: Save properties to a file
FileOutputStream fos = new FileOutputStream(configFilePath);
properties.store(fos, "My Application Settings");
Note that the output stream should be closed after calling the store() method:

Java Code: Close the output stream
            if (fos != null) {
                fos.close();
            }
Content of the text/XML file is replaced completely with new values, and the order of lines is random for each call of store() method. That means, if you open the file and write something manually to it, the store() method will overwrite your changes.

Comments

We can put comment lines into the properties file when saving by calling the store() method that accepts a comment string.

  • Comments in text file start with the # character.
  • Comments in XML file is between the tags <comment> and </comment>



Escape Unicode characters

Since the store() method writes data to file using ISO 8859-1 encoding, for characters that are not in that encoding, we must escape them in the form of: \uxxxx where xxxx is the hexadecimal value of the character, for example:

\u00E9 for character é


Writing the utility class

Based on what we have studied so far, we will create a utility class, ConfigurationManager.java, to encapsulate the most common tasks: load, read, update properties and save. The format is either text file or XML. Some notices about the implementation:

  • The class encapsulates a Properties object and exposes methods to get, set properties values and save to file.
  • The path of configuration file and the format type are specified in the constructor and stored in private variables.
  • The constructor tries to load the configuration file first, and if the file does not exist, it will create a new one and put some default settings. This is a common approach. You would add more default properties, as per your application’s requirement.



Here is the code of the class:

Java Code: Code of ConfigurationManager class
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

public class ConfigurationManager {
    private String configFilePath;
    private Properties properties = new Properties();
    private boolean isXML;
   
    public ConfigurationManager(String configFilePath, boolean isXML) throws IOException {
        this.configFilePath = configFilePath;
        this.isXML = isXML;
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(configFilePath);
            if (isXML) {
                properties.loadFromXML(fis);
            } else {
                properties.load(fis);
            }
        } catch (FileNotFoundException ex) {
            // creates the configuration file and set default properties
            setDefaults();
            save();
        } finally {
            if (fis != null) {
                fis.close();
            }
        }
    }
   
    private void setDefaults() {
        properties.put("host", "localhost");
        properties.put("port", "1521");
        properties.put("user", "root");
        properties.put("pass", "ssap");       
    }
   
    public void save() throws IOException {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(configFilePath);
            if (isXML) {
                properties.storeToXML(fos, "My Application Settings");
            } else {
                properties.store(fos, "My Application Settings");
            }
        } finally {
            if (fos != null) {
                fos.close();
            }
        }
    }
   
    public String getProperty(String key) {
        return properties.getProperty(key);
    }
   
    public String getProperty(String key, String defaultValue) {
        return properties.getProperty(key, defaultValue);
    }
   
    public void setProperty(String key, String value) {
        properties.setProperty(key, value);
    }
}
And here is a test class:

Java Code: Code of test class
import java.io.IOException;

public class ConfigAppTest {
    private String configFilePath = "D:/myapp.properties";
    private String xmlConfig = "D:/myapp.xml";
   
    public static void main(String... args) throws IOException {
        ConfigAppTest tester = new ConfigAppTest();
        tester.testSave();
        tester.testLoad();
    }
   
    public void testSave() throws IOException {
        ConfigurationManager config = null;
        // test with text file
        config = new ConfigurationManager(configFilePath, false);
        config.setProperty("host", "192.168.1.1");
        config.setProperty("port", "5432");
        config.setProperty("user", "postgres");
        config.setProperty("pass", "sergtsop");
        config.save();
       
        // test with XML file
        config = new ConfigurationManager(xmlConfig, true);
        config.setProperty("host", "183.152.181.1");
        config.setProperty("port", "955");
        config.setProperty("user", "admin");
        config.setProperty("pass", "nimda");
        config.save();       
    }
   
    public void testLoad() throws IOException {
        ConfigurationManager config = null;
        // test with text file
        config = new ConfigurationManager(configFilePath, false);
        printProperties(config);
       
        System.out.println("==================================");
       
        config = new ConfigurationManager(xmlConfig, true);
        printProperties(config);
    }

    private void printProperties(ConfigurationManager config) {
        System.out.println("host = " + config.getProperty("host"));
        System.out.println("port = " + config.getProperty("port"));
        System.out.println("user = " + config.getProperty("user"));
        System.out.println("pass = " + config.getProperty("pass"));
    }
}
The ConfigAppTest class has two methods testSave() and testLoad() to test the ConfigurationManager.class, and the printProperties() method prints out the settings read from the configuration file.


Conclusion

So far we have walked through the API and written a utility class for handling most common operations with a configuration file such as loading, reading properties, updating properties, and saving the changes back to the underlying file. The utility class can be re-used across applications without or with little modification. Thanks to the Java’s Properties class!

Submit "How to use properties file in Java" to Facebook Submit "How to use properties file in Java" to Digg Submit "How to use properties file in Java" to del.icio.us Submit "How to use properties file in Java" to StumbleUpon Submit "How to use properties file in Java" to Google

Categories
Properties

Comments