encoding - Codificación UTF-8 de propiedades Java en Eclipse





(11)


Properties props = new Properties();
URL resource = getClass().getClassLoader().getResource("data.properties");         
props.load(new InputStreamReader(resource.openStream(), "UTF8"));

Funciona de maravilla

:-)

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.




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




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();
}



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?




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 ?




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");



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.




Te recomiendo que uses Attesoro ( http://attesoro.org/ ). Es simple y fácil de usar. Y está hecho en java.




Hay una manera mucho más fácil:

props.load(new InputStreamReader(new FileInputStream("properties_file"), "UTF8"));






En Java solo se pasan las referencias y se pasan por valor:

Todos los argumentos de Java se pasan por valor (la referencia se copia cuando la utiliza el método):

En el caso de los tipos primitivos, el comportamiento de Java es simple: el valor se copia en otra instancia del tipo primitivo.

En el caso de los Objetos, esto es lo mismo: las variables del Objeto son punteros (depósitos) que contienen solo la dirección del Objeto que se creó usando la palabra clave "nuevo", y se copian como tipos primitivos.

El comportamiento puede parecer diferente de los tipos primitivos: debido a que la variable de objeto copiada contiene la misma dirección (para el mismo Objeto), el contenido / miembros del Objeto aún podrían modificarse dentro de un método y luego acceder al exterior, dando la ilusión de que el Objeto (que contiene) Se pasó por referencia.

"String" Los objetos parecen ser un ejemplo perfecto para la leyenda urbana que dice que "los objetos se pasan por referencia":

En efecto, dentro de un método nunca podrá actualizar el valor de un String pasado como argumento:

Un objeto de cadena, contiene caracteres por una matriz declarada final que no se puede modificar. Solo la dirección del Objeto podría ser reemplazada por otra utilizando "nuevo". El uso de "nuevo" para actualizar la variable no permitirá que se acceda al Objeto desde el exterior, ya que la variable se pasó inicialmente por valor y se copió.





java eclipse encoding utf-8