convertir - java import utf 8
Codificación de caracteres UTF-8 en Java (4)
Tengo algunos problemas para obtener un texto en francés para convertirlo a UTF8 para que se pueda mostrar correctamente, ya sea en una consola, archivo de texto o en un elemento de la GUI.
La cadena original es
HANDICAP╔ES
que se supone que es
HANDICAPÉES
Aquí hay un fragmento de código que muestra cómo estoy usando el controlador de la base de datos de jackcess para leer en el archivo Acccess MDB en un entorno Eclipse / Linux.
Database database = Database.open(new File(filepath));
Table table = database.getTable(tableName, true);
Iterator rowIter = table.iterator();
while (rowIter.hasNext()) {
Map<String, Object> row = this.rowIter.next();
// convert fields to UTF
Map<String, Object> rowUTF = new HashMap<String, Object>();
try {
for (String key : row.keySet()) {
Object o = row.get(key);
if (o != null) {
String valueCP850 = o.toString();
// String nameUTF8 = new String(valueCP850.getBytes("CP850"), "UTF8"); // does not work!
String valueISO = new String(valueCP850.getBytes("CP850"), "ISO-8859-1");
String valueUTF8 = new String(valueISO.getBytes(), "UTF-8"); // works!
rowUTF.put(key, valueUTF8);
}
}
} catch (UnsupportedEncodingException e) {
System.err.println("Encoding exception: " + e);
}
}
En el código, verá dónde quiero convertir directamente a UTF8, que no parece funcionar, así que tengo que hacer una doble conversión. También tenga en cuenta que no parece haber una manera de especificar el tipo de codificación cuando se utiliza el controlador de jackcess.
Gracias, Cam
Puede especificar la codificación al establecer la conexión. De esta manera fue perfecto y resolver mi problema de codificación:
DatabaseImpl open = DatabaseImpl.open(new File("main.mdb"), true, null, Database.DEFAULT_AUTO_SYNC, java.nio.charset.Charset.availableCharsets().get("windows-1251"), null, null);
Table table = open.getTable("FolderInfo");
Usar " ISO-8859-1 " me ayudó a lidiar con los caracteres franceses.
Nuevo análisis, basado en nueva información.
Parece que su problema es con la codificación del texto antes de que se almacenara en Access DB. Parece que se codificó como ISO-8859-1 o Windows-1252, pero se decodificó como cp850, lo que hace que la cadena HANDICAP╔ES
se almacene en el DB.
Habiendo recuperado correctamente esa cadena de la base de datos, ahora intenta invertir el error de codificación original y recuperar la cadena como debería haberse almacenado: HANDICAPÉES
. Y lo estás logrando con esta línea:
String valueISO = new String(valueCP850.getBytes("CP850"), "ISO-8859-1");
getBytes("CP850")
convierte el carácter ╔
en el valor 0xC9
byte, y el constructor String lo decodifica de acuerdo con ISO-8859-1, lo que da como resultado el carácter É
. La siguiente línea:
String valueUTF8 = new String(valueISO.getBytes(), "UTF-8");
...no hace nada. getBytes()
codifica la cadena en la codificación predeterminada de la plataforma, que es UTF-8 en su sistema Linux. Entonces el constructor String lo decodifica con la misma codificación. Elimina esa línea y aún deberías obtener el mismo resultado.
Más al punto, su intento de crear una "cadena UTF-8" fue equivocado. No necesita preocuparse por la codificación de las cadenas de Java, siempre son UTF-16. Cuando traes texto a una aplicación Java, solo necesitas asegurarte de decodificarlo con la codificación correcta.
Y si mi análisis es correcto, su controlador de Access está decodificando correctamente; el problema está en el otro extremo, posiblemente antes de que el DB aparezca en escena. Eso es lo que necesita corregir, ya que no se puede contar con que el new String(getBytes())
hack new String(getBytes())
funcione en todos los casos.
Análisis original, basado en ninguna información. : - /
Si ve HANDICAP╔ES
en la consola, probablemente no haya ningún problema. Dado este código:
System.out.println("HANDICAPÉES");
La JVM convierte la cadena (Unicode) a la codificación predeterminada de la plataforma, windows-1252, antes de enviarla a la consola. Luego la consola decodifica eso usando su propia codificación predeterminada, que resulta ser cp850. Entonces la consola lo muestra mal, pero eso es normal. Si desea que se muestre correctamente, puede cambiar la codificación de la consola con este comando:
CHCP 1252
Para mostrar la cadena en un elemento GUI, como JLabel, no tiene que hacer nada especial. Solo asegúrate de usar una fuente que pueda mostrar todos los caracteres, pero eso no debería ser un problema para el francés.
En cuanto a escribir en un archivo, simplemente especifique la codificación deseada al crear el escritor:
OutputStreamWriter osw = new OutputStreamWriter(
new FileOutputStream("myFile.txt"), "UTF-8");
String s = "HANDICAP╔ES";
System.out.println(new String(s.getBytes("CP850"), "ISO-8859-1")); // HANDICAPÉES
Esto muestra el valor de cadena correcto. Esto significa que originalmente se codificó / decodificó con ISO-8859-1 y luego se codificó incorrectamente con CP850 (originalmente CP1252 también conocido como Windows ANSI como se señala en un comentario, de hecho también es posible ya que É
tiene el mismo punto de código allí que en ISO-8859- 1).
Alinee su entorno y las tuberías binarias para usar la codificación de caracteres única y la misma. No puedes y no debes convertir entre ellos. Corre el riesgo de perder información en el rango no ASCII de esa manera.
Nota: NO use el fragmento de código anterior para "arreglar" el problema. Esa no sería la solución correcta.
Actualización : al parecer, todavía estás luchando con el problema. Repetiré las partes importantes de la respuesta:
Alinee su entorno y las tuberías binarias para usar la codificación de caracteres única y la misma .
No puede y no debe convertir entre ellos. Corre el riesgo de perder información en el rango no ASCII de esa manera.
NO use el fragmento de código anterior para "arreglar" el problema. Esa no sería la solución correcta .
Para solucionar el problema, debe elegir la codificación de caracteres X que desea utilizar en toda la aplicación. Sugiero UTF-8
. Actualice MS Access para usar la codificación X. Actualice su entorno de desarrollo para usar la codificación X. Actualice los lectores y escritores java.io
en su código para usar la codificación X. Actualice su editor para leer / escribir archivos con la codificación X. Actualice la interfaz de usuario de la aplicación para usar la codificación X. No use Y o Z o lo que sea en algún paso. Si los caracteres ya están dañados en algún almacén de datos (MS Access, archivos, etc.), entonces necesita repararlo reemplazando manualmente los caracteres en el almacén de datos. No use Java para esto.
Si realmente está utilizando el "símbolo del sistema" como interfaz de usuario, entonces en realidad está perdido. No es compatible con UTF-8. Como se sugiere en los comentarios y en el artículo vinculado en los comentarios, debe crear una aplicación Swing en lugar de confiar en el entorno de solicitud de comando restringido.