Codificación UTF-8 de propiedades Java en Eclipse
encoding (12)
Recientemente tuve que cambiar la codificación de la aplicación web en la que estoy trabajando, desde ISO-xx
a utf8
. Todo fue sin problemas, excepto los archivos de propiedades. -Dfile.encoding=UTF-8
en eclipse.ini
y los archivos normales funcionan bien. Sin embargo, las propiedades muestran un comportamiento extraño.
Si utf8
propiedades codificadas de utf8
desde Notepad ++ y las utf8
en Eclipse, se muestran y funcionan bien. Cuando vuelvo a abrir el archivo de propiedades, veo algunos caracteres Unicode en lugar de los propios, como:
Zur/u00EF/u00BF/u00BDck instead of Zurück
pero la aplicación todavía funciona bien. Si comienzo a editar las propiedades, agrego algunos caracteres especiales y las guardo, se muestran correctamente, sin embargo, no funcionan y todos los caracteres especiales que antes funcionaban ya no funcionan.
Cuando comparo la versión local con CVS, puedo ver los caracteres especiales correctamente en el archivo remoto y, después de la actualización, comienzo de nuevo: la aplicación funciona, pero Eclipse muestra los caracteres Unicode.
Intenté cambiar la codificación del archivo haciendo clic con el botón derecho y seleccionando "Otro: UTF8", pero no me ayudó. También dijo: "determinado a partir del contenido: ISO-8859-1"
Estoy usando Java 6 y Jboss Developer basado en Eclipse 3.3
Puedo vivir con esto editando las propiedades en Notepad ++ y pegándolas en Eclipse, pero le agradecería si alguien pudiera ayudarme a arreglar esto en Eclipse.
Esto parece funcionar solo para algunos personajes ... incluyendo caracteres especiales para alemán, portugués y francés. Sin embargo, tuve problemas con los caracteres rusos, hindi y mandarín. Estos no se convierten al formato de propiedades ''native2ascii'', sino que se guardan con ?? ?? ??
La única forma en que podría hacer que mi aplicación muestre estos caracteres correctamente es poniéndolos en el archivo de propiedades traducido al formato UTF-8, como / u0915 en lugar de क o / u044F en lugar de я. ¿Algún consejo?
Hay demasiados puntos en el proceso que describe donde pueden ocurrir errores, así que no trataré de adivinar qué está haciendo mal, pero creo que sé lo que está sucediendo bajo el capó.
EF BF BD
es la forma UTF-8 codificada de U+FFFD
, el carácter de reemplazo estándar insertado por los decodificadores cuando se encuentran con una entrada mal formada. Parece que su texto se guarda como ISO-8859-1, luego se lee como si fuera UTF-8, luego se guarda como UTF-8 y luego se convierte al formato de Propiedades usando native2ascii
usando la codificación predeterminada de la plataforma (por ejemplo, Windows- 1252).
ü => 0xFC // save as ISO-8859-1 0xFC => U+FFFD // read as UTF-8 U+FFFD => 0xEF 0xBF 0xBD // save as UTF-8 0xEF 0xBF 0xBD => /u00EF/u00BF/u00BD // native2ascii
Le sugiero que deje la propiedad "file.encoding" sola. Como "file.separator" y "line.separator", no es tan útil como cabría esperar. En su lugar, adquiera el hábito de especificar siempre una codificación al leer y escribir archivos de texto.
Hay una manera mucho más fácil:
props.load(new InputStreamReader(new FileInputStream("properties_file"), "UTF8"));
Los archivos de propiedades son ISO-8859-1 por definición; consulte los documentos para la clase Properties .
Spring tiene un reemplazo que puede cargarse con una codificación específica, usando PropertiesFactoryBean
.
EDITAR: Como notó Laurence en los comentarios, Java 1.6 introdujo sobrecargas para load
y store
que toman un Reader
/ Writer
. Esto significa que puede crear un lector para el archivo con la codificación que desee y pasarlo a la load
. Lamentablemente, FileReader
aún no le permite especificar la codificación en el constructor (aargh), por lo que tendrá que encadenar FileInputStream
y InputStreamReader
juntos. Sin embargo, funcionará.
Por ejemplo, para leer un archivo usando UTF-8:
Properties properties = new Properties();
InputStream inputStream = new FileInputStream("path/to/file");
try {
Reader reader = new InputStreamReader(inputStream, "UTF-8");
try {
properties.load(reader);
} finally {
reader.close();
}
} finally {
inputStream.close();
}
No es un problema con Eclipse. Si está utilizando la clase de Propiedades para leer y almacenar el archivo de propiedades, la clase escapará a todos los caracteres especiales.
De la documentación de la clase:
Al guardar propiedades en una secuencia o cargarlas desde una secuencia, se utiliza la codificación de caracteres ISO 8859-1. Para los caracteres que no se pueden representar directamente en esta codificación, se usan escapes Unicode; sin embargo, solo se permite un único carácter ''u'' en una secuencia de escape. La herramienta native2ascii se puede usar para convertir archivos de propiedades a otras codificaciones de caracteres.
Los caracteres de menos de / u0020 y los caracteres mayores que / u007E se escriben como / uxxxx para el valor hexadecimal apropiado xxxx.
No pierdas tu tiempo, puedes usar el complemento Resource Bundle en Eclipse
Puede definir archivos .properties UTF-8 para almacenar sus traducciones y usar ResourceBundle, para obtener valores. Para evitar problemas, puede cambiar la codificación:
String value = RESOURCE_BUNDLE.getString(key);
return new String(value.getBytes("ISO-8859-1"), "UTF-8");
Si las propiedades son para XML o HTML, es más seguro usar entidades XML. Son más feos de leer, pero significa que el archivo de propiedades puede tratarse como ASCII directo, por lo que nada se arruinará.
Tenga en cuenta que HTML tiene entidades que XML no tiene, así que lo mantengo seguro utilizando XML directo: http://www.w3.org/TR/html4/sgml/entities.html
Solo otro plugin de Eclipse para archivos * .properties:
Te recomiendo que uses Attesoro ( http://attesoro.org/ ). Es simple y fácil de usar. Y está hecho en java.
Properties props = new Properties();
URL resource = getClass().getClassLoader().getResource("data.properties");
props.load(new InputStreamReader(resource.openStream(), "UTF8"));
Funciona de maravilla
:-)
Properties props = new Properties();
URL resource = getClass().getClassLoader().getResource("data.properties");
props.load(new InputStreamReader(resource.openStream(), "UTF8"));
esto funciona bien en Java 1.6. ¿Cómo puedo hacer esto en 1.5, ya que la clase Propiedades no tiene un método para analizar el InputStreamReader
?