4

I need to add or change value in property file and save this file layout(coments, order etc). If i use java.util.Properties all comments will be deleted and its changed order. Looks like PropertiesConfiguration from Apache Commons can help me with that but i have problem in saving.

In property file i have this lines(as example):

#Comments Test = Тест 

When properties file saved this line converted in:

Test = \u0422\u0435\u0441\u0442 

Given code example:

public void writeProperty(String key, String value) { try { config = new PropertiesConfiguration(sFileName); config.setEncoding("UTF-8"); config.setProperty(key, value); config.save(); } catch (ConfigurationException e) { System.out.println("Error"); e.printStackTrace(); } } 

2 Answers 2

5

It is supposed to be that way. Property files are defined to be in ISO-8859-1 encoding and that Unicode characters have to be escaped accordingly.

Changing that would break the API definition, resulting in a non-standard property file.

See the according article on wikipedia for details.

Sign up to request clarification or add additional context in comments.

Comments

0

Since Java 9 the default for .properties of PropertyResourceBundles is UTF-8 as stated here so you might have a good reasons to write properties with the UTF-8 symbols.

For the org.apache.commons.configuration2, you can achieve this by overriding the default ValueTransformer used for escaping characters

Kotlin code:

import org.apache.commons.configuration2.PropertiesConfiguration import org.apache.commons.configuration2.PropertiesConfiguration.DefaultIOFactory import org.apache.commons.configuration2.PropertiesConfiguration.PropertiesWriter import org.apache.commons.configuration2.convert.ListDelimiterHandler import org.apache.commons.configuration2.convert.ValueTransformer import org.apache.commons.text.translate.AggregateTranslator import org.apache.commons.text.translate.EntityArrays import org.apache.commons.text.translate.LookupTranslator import java.io.ByteArrayInputStream import java.io.InputStream import java.io.StringWriter import java.io.Writer /** * This class is custom implementation of the [ValueTransformer] that prevents escaping of UTF-8 characters * UTF-8 is supported in properties files by Java 9 */ private class Utf8ValueTransformer : ValueTransformer { companion object { private val charsEscape = mapOf<CharSequence, CharSequence>("\\" to "\\\\") private val escapeProperties = AggregateTranslator( LookupTranslator(charsEscape), LookupTranslator( EntityArrays.JAVA_CTRL_CHARS_ESCAPE ) ) } override fun transformValue(p0: Any?): Any { val strVal = p0.toString() return escapeProperties.translate(strVal) } } 

Then you have to extend the DefaultIOFactory:

private class Utf8IoFactory : DefaultIOFactory() { companion object { private val valueTransformer = Utf8ValueTransformer() } override fun createPropertiesWriter(out: Writer?, handler: ListDelimiterHandler?): PropertiesWriter { return PropertiesWriter(out, handler, valueTransformer) } } 

And finally you can get the result with UTF-8 characters:

 private fun PropertiesConfiguration.asByteArray(): ByteArray { val writer = StringWriter() this.ioFactory = Utf8IoFactory() this.write(writer) return writer.toString().toByteArray() } 

Comments