2009-03-16 9 views
56

¿Alguien sabe cómo convertir una cadena de ISO-8859-1 a UTF-8 y volver a Java?¿Cómo convierto entre ISO-8859-1 y UTF-8 en Java?

Estoy obteniendo una cadena de la web y guardándola en el RMS (J2ME), pero quiero conservar los caracteres especiales y obtener la cadena del RMS pero con la codificación ISO-8859-1. ¿Cómo hago esto?

+0

posible duplicado de [Codificación de conversión en java] (http: // stackoverflow.com/questions/229015/encoding-conversion-in-java) – kamaci

Respuesta

87

En general, no puede hacer esto. UTF-8 es capaz de codificar cualquier punto de código Unicode. ISO-8859-1 solo puede manejar una pequeña fracción de ellos. Por lo tanto, la transcodificación de ISO-8859-1 a UTF-8 no es un problema. Si se retrocede de UTF-8 a ISO-8859-1, aparecerán "caracteres de reemplazo" (& # xFFFD;) en el texto cuando se encuentren caracteres no admitidos.

transcodificar texto:

byte[] latin1 = ... 
byte[] utf8 = new String(latin1, "ISO-8859-1").getBytes("UTF-8"); 

o

byte[] utf8 = ... 
byte[] latin1 = new String(utf8, "UTF-8").getBytes("ISO-8859-1"); 

Usted puede ejercer un mayor control utilizando el menor nivel Charset API. Por ejemplo, puede generar una excepción cuando se encuentre un carácter no codificable o utilizar un carácter diferente para reemplazar el texto.

+1

Para obtener más información sobre la codificación de caracteres y por qué legítimamente no tiene mucho sentido pasar de UTF-8 a ISO-8859 (o ASCII o ANSI para el caso), consulte esta explicación: http://www.joelonsoftware.com /articles/Unicode.html –

+0

Aquí hay un buen resumen de dicho enlace: 'Hay cientos de codificaciones tradicionales que solo pueden almacenar algunos puntos de código correctamente y cambiar todos los demás puntos de código en signos de interrogación. Algunas codificaciones populares de texto en inglés son Windows-1252 (el estándar de Windows 9x para los idiomas de Europa occidental) e ISO-8859-1, también conocido como Latin-1 (también es útil para cualquier idioma de Europa occidental). Pero intente almacenar letras rusas o hebreas [o caracteres especiales] en estas codificaciones y obtendrá un montón de signos de interrogación. UTF 7, 8, 16 y 32 tienen la agradable propiedad de poder almacenar cualquier punto de código correctamente. –

+0

Vale la pena mencionar que Windows-1252 (Windows Latin 1) se extiende ISO-8859-1 (Latin 1 oficial) rellenando algunos de los caracteres "control Unicode" 0x80 - 0xbf. Incluso los navegadores en Mac y Linux respetan eso. Entonces, en algunos puntos usa Windows-1252 en su lugar. –

6

Si usted tiene un String, se puede hacer eso:

String s = "test"; 
try { 
    s.getBytes("UTF-8"); 
} catch(UnsupportedEncodingException uee) { 
    uee.printStackTrace(); 
} 

Si usted tiene un 'roto' String, que hizo algo mal, la conversión de un String a un String en otra codificación no es defenetely el camino ¡ir! Puede convertir un String en un byte[] y viceversa (dada una codificación). En Java String s están codificados con AFAIK UTF-16, pero eso es un detalle de implementación.

Digamos que tienes una InputStream, se puede leer en un byte[] y luego convertir eso a un String usando

byte[] bs = ...; 
String s; 
try { 
    s = new String(bs, encoding); 
} catch(UnsupportedEncodingException uee) { 
    uee.printStackTrace(); 
} 

o incluso mejor (gracias a Erickson) utiliza InputStreamReader así:

InputStreamReader isr; 
try { 
    isr = new InputStreamReader(inputStream, encoding); 
} catch(UnsupportedEncodingException uee) { 
    uee.printStackTrace(); 
} 
+1

Si tiene un InputStream, debe envolverlo con un InputStreamReader. – erickson

3

Aquí es una manera fácil con String salida (he creado un método para hacer esto):

public static String (String input){ 
    String output = ""; 
    try { 
     /* From ISO-8859-1 to UTF-8 */ 
     output = new String(input.getBytes("ISO-8859-1"), "UTF-8"); 
     /* From UTF-8 to ISO-8859-1 */ 
     output = new String(input.getBytes("UTF-8"), "ISO-8859-1"); 
    } catch (UnsupportedEncodingException e) { 
     e.printStackTrace(); 
    } 
    return output; 
} 
// Example 
input = "Música"; 
output = "Música"; 
4

que funcionó para mí: ("üzüm Baglari" es la correcta por escrito en Turquía)

Convertir ISO-8859-1 a UTF-8:

String encodedWithISO88591 = "üzüm baÄları"; 
String decodedToUTF8 = new String(encodedWithISO88591.getBytes("ISO-8859-1"), "UTF-8"); 
//Result, decodedToUTF8 --> "üzüm bağları" 

Convert UTF-8 a ISO-8859-1

String encodedWithUTF8 = "üzüm bağları"; 
String decodedToISO88591 = new String(encodedWithUTF8.getBytes("UTF-8"), "ISO-8859-1"); 
//Result, decodedToISO88591 --> "üzüm baÄları" 
+0

¿Qué pasaría si escribe el siguiente código: 'String a = new String (encodedWithUTF8.getBytes (" ISO88591 ")," ISO-8859-1 ")' y 'String b = new String (encodedWithUTF8.getBytes (" ISO88591 ")," UTF-8 ")'? Si la cadena está en una codificación y obtenemos bytes usando la otra, ¿qué está pasando debajo del capó? – parsecer

+0

Puedes probarlos y ver los resultados en tu IDE, y si sigues esta URL http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#String (byte [] ,% 20java.nio.charset.Charset) verá la definición del método. No sé el detalle exacto del proceso. – webmaster

+1

Si alguien necesita esto, creo que los comandos anteriores harían lo siguiente: 'a' tomaría los bytes de' UTF-8', los convertiría en bytes 'ISO' y luego usaría una tabla' bytes-> chars' of ' Codificación ISO' para imprimir la cadena. En el caso de la cadena 'b' usaría una tabla' bytes-> chars' de 'UTF-8', por lo tanto mapeando esencialmente bytes' ISO' de acuerdo con las reglas 'UTF'. 'a' se imprimirá bien a pesar de que es' ISO', porque Java no estropea su almacenamiento interno de bytes. 'b' puede dañarse porque algunos de los caracteres' ISO' se imprimirán como si pertenecieran a la codificación 'UTF'. – parsecer

0

Apache Commons IO Charsets class puede ser útil:

String utf8String = new String(org.apache.commons.io.Charsets.ISO_8859_1.encode(latinString).array())