228

I have a list of key/value pairs of configuration values I want to store as Java property files, and later load and iterate through.

Questions:

  • Do I need to store the file in the same package as the class which will load them, or is there any specific location where it should be placed?
  • Does the file need to end in any specific extension or is .txt OK?
  • How can I load the file in the code
  • And how can I iterate through the values inside?
0

17 Answers 17

254

You can pass an InputStream to the Property, so your file can pretty much be anywhere, and called anything.

Properties properties = new Properties();
try {
  properties.load(new FileInputStream("path/filename"));
} catch (IOException e) {
  ...
}

Iterate as:

for(String key : properties.stringPropertyNames()) {
  String value = properties.getProperty(key);
  System.out.println(key + " => " + value);
}
4
  • What value is returned when the key is not present in the properties file? Commented Feb 5, 2014 at 7:56
  • 2
    @MitakshGupta If a property with the name you passed is not found in the file or in the default properties list, it returs null. See Javadoc Commented Feb 20, 2014 at 20:20
  • 3
    how does this compare with properties.load(PropertiesReader.class.getResourceAsStream("/properties.properties")); that is, getResourceAsStream versus FileInputStream? pros and cons?
    – Thufir
    Commented Jan 27, 2015 at 4:17
  • Are there any problems because you dont close FileInputStream?
    – DM CHAU
    Commented Jul 3, 2020 at 6:23
81
  • You can store the file anywhere you like. If you want to keep it in your jar file, you'll want to use Class.getResourceAsStream() or ClassLoader.getResourceAsStream() to access it. If it's on the file system it's slightly easier.

  • Any extension is fine, although .properties is more common in my experience

  • Load the file using Properties.load, passing in an InputStream or a StreamReader if you're using Java 6. (If you are using Java 6, I'd probably use UTF-8 and a Reader instead of the default ISO-8859-1 encoding for a stream.)

  • Iterate through it as you'd iterate through a normal Hashtable (which Properties derives from), e.g. using keySet(). Alternatively, you can use the enumeration returned by propertyNames().

1
  • 1
    Thanks Jon, next thing I know I'll be looking up something on joda and you'll answer that too.
    – Flame
    Commented Oct 17, 2012 at 3:57
27

If you put the properties file in the same package as class Foo, you can easily load it with

new Properties().load(Foo.class.getResourceAsStream("file.properties"))

Given that Properties extends Hashtable you can iterate over the values in the same manner as you would in a Hashtable.

If you use the *.properties extension you can get editor support, e.g. Eclipse has a properties file editor.

4
  • 5
    You can do this - but I dislike storing properties files in the same package. You end up with properties files spread all over the place in your application. I'd much rather store all properties files in the root of the app, and load them as "class.getResourceAsStream("\file.properties")" or in some other known location.
    – Nate
    Commented Aug 23, 2009 at 12:06
  • Nate, that's true. However, in some scenarios the deployed location is not known (e.g. everything of your particular component is bundled into some archive). In such cases it can be quite convenient to say 'it's with that class, wherever that class ends up to be'. Also to avoid spreading the files all over, a single config package can be used for all the property files. Commented Aug 23, 2009 at 15:40
  • 1
    Fabian, both of those cases work with my comment - it's based on the classpath - not the filesystem.
    – Nate
    Commented Aug 25, 2009 at 14:27
  • 2
    For anyone trying to get Nate's example to work- the backslash should be replaced with a forward slash. So in this case: 'class.getResourceAsStream("/file.properties")' Commented May 20, 2015 at 19:41
12

There are many ways to create and read properties files:

  1. Store the file in the same package.
  2. Recommend .properties extension however you can choose your own.
  3. Use theses classes located at java.util package => Properties, ListResourceBundle, ResourceBundle classes.
  4. To read properties, use iterator or enumerator or direct methods of Properties or java.lang.System class.

ResourceBundle class:

 ResourceBundle rb = ResourceBundle.getBundle("prop"); // prop.properties
 System.out.println(rb.getString("key"));

Properties class:

Properties ps = new Properties();
ps.Load(new java.io.FileInputStream("my.properties"));
0
5

This load the properties file:

Properties prop = new Properties();
InputStream stream = ...; //the stream to the file
try {
  prop.load(stream);
} finally {
  stream.close();
}

I use to put the .properties file in a directory where I have all the configuration files, I do not put it together with the class that accesses it, but there are no restrictions here.

For the name... I use .properties for verbosity sake, I don't think you should name it .properties if you don't want.

1
  • However, some "extensions" of properties files assume the .properties extension - for example ResourceBundle used in I18N.
    – Nate
    Commented Aug 23, 2009 at 12:07
5

Properties has become legacy. Preferences class is preferred to Properties.

A node in a hierarchical collection of preference data. This class allows applications to store and retrieve user and system preference and configuration data. This data is stored persistently in an implementation-dependent backing store. Typical implementations include flat files, OS-specific registries, directory servers and SQL databases. The user of this class needn't be concerned with details of the backing store.

Unlike properties which are String based key-value pairs, The Preferences class has several methods used to get and put primitive data in the Preferences data store. We can use only the following types of data:

  1. String
  2. boolean
  3. double
  4. float
  5. int
  6. long
  7. byte array

To load the the properties file, either you can provide absolute path Or use getResourceAsStream() if the properties file is present in your classpath.

package com.mypack.test;

import java.io.*;
import java.util.*;
import java.util.prefs.Preferences;

public class PreferencesExample {

    public static void main(String args[]) throws FileNotFoundException {
        Preferences ps = Preferences.userNodeForPackage(PreferencesExample.class);
        // Load file object
        File fileObj = new File("d:\\data.xml");
        try {
            FileInputStream fis = new FileInputStream(fileObj);
            ps.importPreferences(fis);
            System.out.println("Prefereces:"+ps);
            System.out.println("Get property1:"+ps.getInt("property1",10));

        } catch (Exception err) {
            err.printStackTrace();
        }
    }
}

xml file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE preferences SYSTEM 'http://java.sun.com/dtd/preferences.dtd'>
<preferences EXTERNAL_XML_VERSION="1.0">
<root type="user">
<map />
<node name="com">
  <map />
  <node name="mypack">
    <map />
    <node name="test">
      <map>
        <entry key="property1" value="80" />
        <entry key="property2" value="Red" />
      </map>
    </node>
  </node>
</node>
</root>
</preferences>

Have a look at this article on internals of preferences store

5

Example:

Properties pro = new Properties();
FileInputStream in = new FileInputStream("D:/prop/prop.properties");
pro.load(in);
String temp1[];
String temp2[];
// getting values from property file
String username = pro.getProperty("usernamev3");//key value in prop file 
String password = pro.getProperty("passwordv3");//eg. username="zub"
String delimiter = ",";                         //password="abc"
temp1=username.split(delimiter);
temp2=password.split(delimiter);
1
  • what if you have 3 proprties files?
    – Angelina
    Commented Aug 15, 2014 at 16:36
3

In order:

  1. You can store the file pretty much anywhere.
  2. no extension is necessary.
  3. Montecristo has illustrated how to load this. That should work fine.
  4. propertyNames() gives you an enumeration to iterate through.
2
  • 2. no extension is necessary, Can you please provide me any reference for this statement please. I have confusion on that. Commented Dec 24, 2014 at 4:03
  • Note that you can load the properties via an input stream. As such the properties have no knowledge of where that inputstream came from (a file? a socket?) and consequently can't enforce a naming standard Commented Dec 24, 2014 at 13:46
3

By default, Java opens it in the working directory of your application (this behavior actually depends on the OS used). To load a file, do:

Properties props = new java.util.Properties();
FileInputStream fis new FileInputStream("myfile.txt");
props.load(fis)

As such, any file extension can be used for property file. Additionally, the file can also be stored anywhere, as long as you can use a FileInputStream.

On a related note if you use a modern framework, the framework may provide additionnal ways of opening a property file. For example, Spring provide a ClassPathResource to load a property file using a package name from inside a JAR file.

As for iterating through the properties, once the properties are loaded they are stored in the java.util.Properties object, which offer the propertyNames() method.

3

Reading a properties file and loading its contents to Properties

String filename = "sample.properties";
Properties properties = new Properties();

input = this.getClass().getClassLoader().getResourceAsStream(filename);
properties.load(input);

The following is the efficient way to iterate over a Properties

    for (Entry<Object, Object> entry : properties.entrySet()) {

        System.out.println(entry.getKey() + " => " + entry.getValue());
    }
3

In Java 8 to get all your properties

public static Map<String, String> readPropertiesFile(String location) throws Exception {

    Map<String, String> properties = new HashMap<>();

    Properties props = new Properties();
    props.load(new FileInputStream(new File(location)));

    props.forEach((key, value) -> {
        properties.put(key.toString(), value.toString());
    });

    return properties;
}
2

1) It is good to have your property file in classpath but you can place it anywhere in project.

Below is how you load property file from classpath and read all properties.

Properties prop = new Properties();
InputStream input = null;

try {

    String filename = "path to property file";
    input = getClass().getClassLoader().getResourceAsStream(filename);
    if (input == null) {
        System.out.println("Sorry, unable to find " + filename);
        return;
    }

    prop.load(input);

    Enumeration<?> e = prop.propertyNames();
    while (e.hasMoreElements()) {
        String key = (String) e.nextElement();
        String value = prop.getProperty(key);
        System.out.println("Key : " + key + ", Value : " + value);
    }

} catch (IOException ex) {
    ex.printStackTrace();
} finally {
    if (input != null) {
        try {
            input.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2) Property files have the extension as .properties

1

Here is another way to iterate over the properties:

Enumeration eProps = properties.propertyNames();
while (eProps.hasMoreElements()) { 
    String key = (String) eProps.nextElement(); 
    String value = properties.getProperty(key); 
    System.out.println(key + " => " + value); 
}
1
  • 2
    I'm totally sorry. I reviewed the code in Zed's answer and it works quite well... I don't know what I thought back then... Actually his solution is nicer than mine, I think...
    – dertoni
    Commented Jul 15, 2010 at 9:11
1

I have written on this property framework for the last year. It will provide of multiple ways to load properties, and have them strongly typed as well.

Have a look at http://sourceforge.net/projects/jhpropertiestyp/

JHPropertiesTyped will give the developer strongly typed properties. Easy to integrate in existing projects. Handled by a large series for property types. Gives the ability to one-line initialize properties via property IO implementations. Gives the developer the ability to create own property types and property io's. Web demo is also available, screenshots shown above. Also have a standard implementation for a web front end to manage properties, if you choose to use it.

Complete documentation, tutorial, javadoc, faq etc is a available on the project webpage.

1

You can load the property file suing the following way:

InputStream is = new Test().getClass().getClassLoader().getResourceAsStream("app.properties");
        Properties props =  new Properties();
        props.load(is);

And then you can iterate over the map using a lambda expression like:

props.stringPropertyNames().forEach(key -> {
            System.out.println("Key is :"+key + " and Value is :"+props.getProperty(key));
        });
0

Here ready static class

import java.io.*;
import java.util.Properties;
public class Settings {
    public static String Get(String name,String defVal){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            FileReader reader = new FileReader(configFile);
            Properties props = new Properties();
            props.load(reader);
            reader.close();
            return props.getProperty(name);
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
            return defVal;
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
            return defVal;
        } catch (Exception ex){
            logger.error(ex);
            return defVal;
        }
    }
    public static Integer Get(String name,Integer defVal){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            FileReader reader = new FileReader(configFile);
            Properties props = new Properties();
            props.load(reader);
            reader.close();
            return Integer.valueOf(props.getProperty(name));
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
            return defVal;
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
            return defVal;
        } catch (Exception ex){
            logger.error(ex);
            return defVal;
        }
    }
    public static Boolean Get(String name,Boolean defVal){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            FileReader reader = new FileReader(configFile);
            Properties props = new Properties();
            props.load(reader);
            reader.close();
            return Boolean.valueOf(props.getProperty(name));
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
            return defVal;
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
            return defVal;
        } catch (Exception ex){
            logger.error(ex);
            return defVal;
        }
    }
    public static void Set(String name, String value){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            Properties props = new Properties();
            FileReader reader = new FileReader(configFile);
            props.load(reader);
            props.setProperty(name, value.toString());
            FileWriter writer = new FileWriter(configFile);
            props.store(writer, Variables.SETTINGS_COMMENT);
            writer.close();
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
        } catch (Exception ex){
            logger.error(ex);
        }
    }
    public static void Set(String name, Integer value){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            Properties props = new Properties();
            FileReader reader = new FileReader(configFile);
            props.load(reader);
            props.setProperty(name, value.toString());
            FileWriter writer = new FileWriter(configFile);
            props.store(writer,Variables.SETTINGS_COMMENT);
            writer.close();
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
        } catch (Exception ex){
            logger.error(ex);
        }
    }
    public static void Set(String name, Boolean value){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            Properties props = new Properties();
            FileReader reader = new FileReader(configFile);
            props.load(reader);
            props.setProperty(name, value.toString());
            FileWriter writer = new FileWriter(configFile);
            props.store(writer,Variables.SETTINGS_COMMENT);
            writer.close();
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
        } catch (Exception ex){
            logger.error(ex);
        }
    }
}

Here sample:

Settings.Set("valueName1","value");
String val1=Settings.Get("valueName1","value");
Settings.Set("valueName2",true);
Boolean val2=Settings.Get("valueName2",true);
Settings.Set("valueName3",100);
Integer val3=Settings.Get("valueName3",100);
0

in my opinion other ways are deprecated when we can do it very simple as below:

@PropertySource("classpath:application.properties")
public class SomeClass{

    @Autowired
    private Environment env;

    public void readProperty() {
        env.getProperty("language");
    }

}

it is so simple but i think that's the best way!! Enjoy

Not the answer you're looking for? Browse other questions tagged or ask your own question.