Read/Write Properties Files in Java Many years ago I covered how to read and write properties files in Java. Recently, I had to add this feature to some software, so I thought I'd quickly review the process for those who missed it the first time.



Many years ago I covered how to read and write properties files in Java. Recently, I had to add this feature to some software, so I thought I'd quickly review the process for those who missed it the first time. We all know the motivation behind configuration, or properties, files — it's bad practice to hard-code values into your code, and it makes more sense to allow them to be overridden at runtime. For instance, you may want to allow the user to set or change the default value of the network port your software listens on, the number of threads created in a thread pool, or the address of a server your software communicates with. The examples go on. Fortunately, Java makes it very easy to read, write, and update properties files in multiple forms, via the java.util.Properties package. Let's take a closer look.

Using the examples above of values you may want to override at runtime, a properties file in the form of named-value pairs is often quick and easy to create. For instance:

ServerAddress=192.168.3.1 ServerPort=80 ThreadCount=5

You would then read such a file in your Java code as:

public void loadParams() { Properties props = new Properties(); InputStream is = null; // First try loading from the current directory try { File f = new File("server.properties"); is = new FileInputStream( f ); } catch ( Exception e ) { is = null; } try { if ( is == null ) { // Try loading from classpath is = getClass().getResourceAsStream("server.properties"); } // Try loading properties from the file (if found) props.load( is ); } catch ( Exception e ) { } serverAddr = props.getProperty("ServerAddress", "192.168.0.1"); serverPort = new Integer(props.getProperty("ServerPort", "8080")); threadCnt = new Integer(props.getProperty("ThreadCount", "5")); }

There's more error checking than code, as is often the case when dealing with files, but it's pretty straightforward. In this case, the code attempts to load the file in the directory where the application was started. If it's not found there, it looks in the classpath for the file. Of course, you can just default to the classpath condition for loading, but I like to check an explicit location first. That's just a personal preference. In either case, if the file isn't found, the default values provided with each call to getProperty are used.

You can use the Java properties API to create the file in the first place, and/or update it later if changes are made through the application itself. The following code is an example of this:

public void saveParamChanges() { try { Properties props = new Properties(); props.setProperty("ServerAddress", serverAddr); props.setProperty("ServerPort", ""+serverPort); props.setProperty("ThreadCount", ""+threadCnt); File f = new File("server.properties"); OutputStream out = new FileOutputStream( f ); props.store(out, "This is an optional header comment string"); } catch (Exception e ) { e.printStackTrace(); } }

What About XML?

Sometimes a simple named-value pair file meets the need just fine, but in other cases, an XML file may be desired. No worries, the Preferences API allows you to effortlessly save and load your properties as XML files as well. And none of the code to read or write the property values needs to change. All you need to do is substitute Properties.store for Properties.storeToXML and provide a more appropriate file name (i.e. server.xml). For example:

public void saveParamChangesAsXML() { try { Properties props = new Properties(); props.setProperty("ServerAddress", serverAddr); props.setProperty("ServerPort", ""+serverPort); props.setProperty("ThreadCount", ""+threadCnt); File f = new File("server.xml"); OutputStream out = new FileOutputStream( f ); props.storeToXML(out, "This is an optional header comment string"); } catch (Exception e ) { e.printStackTrace(); } }

To read the XML properties file, simply change the Properties.load in your code (such as in loadParams() above) to Properties.loadFromXML and specify a proper XML file. That's it!

Happy coding!

-EJB