How to use properties file in Java
by , 02-29-2012 at 09:57 AM (817 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:
Note that we should close the input stream after loading:Java Code: Load a properties fileString configFilePath = “D:/settings.properties”; Properties properties = new Properties(); FileInputStream fis = new FileInputStream(configFilePath); properties.load(fis);
Java Code: Close the input streamif (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:
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 propertyString hostname = properties.getProperty(“host”);
Java Code: Retrieve value of a property, or return a default value if not foundString hostname = properties.getProperty(“host”, “localhost”);
Setting properties
Updating value for a property is straight forward:
Note that the property’s value is not updated in the underlying file until we call the store() methods.Java Code: Set value for a propertyproperties.setProperty(“host”, “192.168.1.1”);
Saving properties file
The following code stores the property list of the Properties object to the underlying file:
Note that the output stream should be closed after calling the store() method:Java Code: Save properties to a fileFileOutputStream fos = new FileOutputStream(configFilePath); properties.store(fos, "My Application Settings");
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.Java Code: Close the output streamif (fos != null) { fos.close(); }
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:
And here is a test class:Java Code: Code of ConfigurationManager classimport 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); } }
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.Java Code: Code of test classimport 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")); } }
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!









Email Blog Entry
Get the info of a socket
This...
Yesterday, 12:50 AM in sixxvirus