Default escape character in Java is '\'.
However, Java properties file has format key=value, it should be considering everything after the first equal as value.
In load(Reader reader) method documentation it says
The key contains all of the characters
in the line starting with the first
non-white space character and up to,
but not including, the first unescaped
'=', ':', or white space character
other than a line terminator. All of
these key termination characters may
be included in the key by escaping
them with a preceding backslash
character; for example,
\:\=
would be the two-character key ":=".
Line terminator characters can be
included using \r and \n escape
sequences. Any white space after the
key is skipped; if the first non-white
space character after the key is '='
or ':', then it is ignored and any
white space characters after it are
also skipped. All remaining characters
on the line become part of the
associated element string; if there
are no remaining characters, the
element is the empty string "". Once
the raw character sequences
constituting the key and element are
identified, escape processing is
performed as described above.
In your specific example you don't need to escape the equals - you only need to escape it if it's part of the key. The properties file format will treat all characters after the first unescaped equals as part of the value.
The best way to avoid this kind of issues it to build properties programmatically and then store them. For example, using code like this:
java.util.Properties props = new java.util.Properties();
props.setProperty("table.whereclause", "where id=100");
props.store(System.out, null);
This would output to System.out the properly escaped version.
In my case the output was:
#Mon Aug 12 13:50:56 EEST 2013
table.whereclause=where id\=100
As you can see, this is an easy way to generate content of .properties files that's guaranteed to be correct. And you can put as many properties as you want.
This method should help to programmatically generate values guaranteed to be 100% compatible with .properties files:
public static String escapePropertyValue(final String value) {
if (value == null) {
return null;
}
try (final StringWriter writer = new StringWriter()) {
final Properties properties = new Properties();
properties.put("escaped", value);
properties.store(writer, null);
writer.flush();
final String stringifiedProperties = writer.toString();
final Pattern pattern = Pattern.compile("(.*?)escaped=(.*?)" + Pattern.quote(System.lineSeparator()) + "*");
final Matcher matcher = pattern.matcher(stringifiedProperties);
if (matcher.find() && matcher.groupCount() <= 2) {
return matcher.group(matcher.groupCount());
}
// This should never happen unless the internal implementation of Properties::store changed
throw new IllegalStateException("Could not escape property value");
} catch (final IOException ex) {
// This should never happen. IOException is only because the interface demands it
throw new IllegalStateException("Could not escape property value", ex);
}
}
You can call it like this:
final String escapedPath = escapePropertyValue("C:\\Users\\X");
writeToFile(escapedPath); // will pass "C\\:\\\\Users\\\\X"
This method a little bit expensive but, writing properties to a file is typically an sporadic operation anyway.