Yet another answer (in January 2018) to the old question (in January 2009).
The specification of Java properties file is described in the JavaDoc of java.util.Properties.load(java.io.Reader)
. One problem is that the specification is a bit complicated than the first impression we may have. Another problem is that some answers here arbitrarily added extra specifications - for example, ;
and '
are regarded as starters of comment lines but they should not be. Double/single quotations around property values are removed but they should not be.
The following are points to be considered.
\n
, \r
, \r\n
or the end of the stream.\
.
, \u0020
), tab (\t
, \u0009
) and form feed (\f
, \u000C
).=
is used as the separator between a key and a value.:
is used as the separator between a key and a value, too.#
or !
as its first non-white space characters, meaning leading white spaces before #
or !
are allowed.\
.=
, :
and white spaces can be embedded in a key if they are escaped by backslashes.\r
and \n
escape sequences.\uxxxx
is used to represent a Unicode character.So, for example, if test.properties
has the following content:
# A comment line that starts with '#'.
# This is a comment line having leading white spaces.
! A comment line that starts with '!'.
key1=value1
key2 : value2
key3 value3
key\
4=value\
4
\u006B\u0065\u00795=\u0076\u0061\u006c\u0075\u00655
\k\e\y\6=\v\a\lu\e\6
\:\ \= = \\colon\\space\\equal
it should be interpreted as the following key-value pairs.
+------+--------------------+
| KEY | VALUE |
+------+--------------------+
| key1 | value1 |
| key2 | value2 |
| key3 | value3 |
| key4 | value4 |
| key5 | value5 |
| key6 | value6 |
| : = | \colon\space\equal |
+------+--------------------+
PropertiesLoader
class in Authlete.Authlete NuGet package can interpret the format of the specification. The example code below:
using System;
using System.IO;
using System.Collections.Generic;
using Authlete.Util;
namespace MyApp
{
class Program
{
public static void Main(string[] args)
{
string file = "test.properties";
IDictionary<string, string> properties;
using (TextReader reader = new StreamReader(file))
{
properties = PropertiesLoader.Load(reader);
}
foreach (var entry in properties)
{
Console.WriteLine($"{entry.Key} = {entry.Value}");
}
}
}
}
will generate this output:
key1 = value1
key2 = value2
key3 = value3
key4 = value4
key5 = value5
key6 = value6
: = = \colon\space\equal
An equivalent example in Java is as follows:
import java.util.*;
import java.io.*;
public class Program
{
public static void main(String[] args) throws IOException
{
String file = "test.properties";
Properties properties = new Properties();
try (Reader reader = new FileReader(file))
{
properties.load(reader);
}
for (Map.Entry<Object, Object> entry : properties.entrySet())
{
System.out.format("%s = %s\n", entry.getKey(), entry.getValue());
}
}
}
The source code, PropertiesLoader.cs
, can be found in authlete-csharp. xUnit tests for PropertiesLoader
are written in PropertiesLoaderTest.cs
.