2008-10-23 33 views

Respuesta

38

Usted no necesita una biblioteca más allá del estándar uno - sólo tiene que utilizar Charset. (Puede usar simplemente los constructores String y los métodos getBytes, pero personalmente no me gusta simplemente trabajar con los nombres de las codificaciones de caracteres. Demasiado espacio para errores ortográficos.)

EDITAR: Como se señala en los comentarios, aún puede use instancias Charset pero tenga la facilidad de uso de los métodos String: new String(bytes, charset) y String.getBytes(charset).

+3

Prefiero nuevas cadenas (byte [], codificación) y String.getBytes (codificación) en la mayoría de los casos, porque son simples líneas simples en comparación con la API más poderosa pero más complicada de Charset (que, por cierto, solo está disponible en Java 1.4+). – Alexander

+3

Sí, es una pena que la API de Charset sea tan complicada. La clase .NET System.Encoding lo hace realmente bien, IMO, y mantiene la funcionalidad fuera de String. –

+0

Enlaces corregidos. Ver http://www.free-scripts.net/html_tutorial/html/topics/urlencoding.htm – VonC

18

CharsetDecoder debería ser lo que está buscando, ¿no?

Muchos protocolos y archivos de red almacenan sus caracteres con un juego de caracteres orientado a bytes como ISO-8859-1 (ISO-Latin-1).
Sin embargo, la codificación de caracteres nativos de Java es Unicode UTF16BE (formato de transformación UCS de dieciséis bits, orden de bytes de big-endian).

Ver Charset. Eso no significa UTF16 es el conjunto de caracteres por defecto (es decir: el "mapeo entre secuencias de dieciséis bits Unicode code units y secuencias de bytes" default):

Cada instancia de la máquina virtual Java tiene un conjunto de caracteres por defecto , que puede ser o no uno de los conjuntos de caracteres estándar.
[US-ASCII, ISO-8859-1 alias ISO-LATIN-1, UTF-8, UTF-16BE, UTF-16LE, UTF-16]
el conjunto de caracteres por defecto se determina durante el arranque de máquina virtual y típicamente depende de la configuración regional y charset siendo utilizado por el sistema operativo subyacente.

Este ejemplo muestra cómo convertir ISO-8859-1 bytes codificados en un ByteBuffer a una cadena en un CharBuffer y viceversa.

// Create the encoder and decoder for ISO-8859-1 
Charset charset = Charset.forName("ISO-8859-1"); 
CharsetDecoder decoder = charset.newDecoder(); 
CharsetEncoder encoder = charset.newEncoder(); 

try { 
    // Convert a string to ISO-LATIN-1 bytes in a ByteBuffer 
    // The new ByteBuffer is ready to be read. 
    ByteBuffer bbuf = encoder.encode(CharBuffer.wrap("a string")); 

    // Convert ISO-LATIN-1 bytes in a ByteBuffer to a character ByteBuffer and then to a string. 
    // The new ByteBuffer is ready to be read. 
    CharBuffer cbuf = decoder.decode(bbuf); 
    String s = cbuf.toString(); 
} catch (CharacterCodingException e) { 
} 
+0

De http://www.exampledepot.com/egs/java.nio.charset/ConvertChar.html – VonC

+3

Unicode no es una codificación! UTF-8, UTF-16 etc. son. Ver http://www.joelonsoftware.com/articles/Unicode.html –

+0

@SealedSun: muy cierto. He arreglado esa sección de "codificación nativa de Java" en mi respuesta. – VonC

0

Es mucho más fácil si piensas en unicode como un conjunto de caracteres (que en realidad es, básicamente es el conjunto numerado de todos los caracteres conocidos). Puede codificarlo como UTF-8 (dependiendo de 1-3 bytes por carácter) o quizás UTF-16 (2 bytes por carácter o 4 bytes utilizando pares de sustitución).

De vuelta en la niebla del tiempo, Java solía usar UCS-2 para codificar el conjunto de caracteres Unicode. Esto solo podría manejar 2 bytes por carácter y ahora está obsoleto. Fue un truco bastante obvio agregar pares de sustitución y pasar a UTF-16.

Mucha gente cree que deberían haber usado UTF-8 en primer lugar. Cuando Java se escribió originalmente unicode tenía más de 65535 caracteres de todos modos ...

0

UTF-8 y UCS-2/UTF-16 se pueden distinguir razonablemente fácilmente mediante una marca de orden de bytes al principio del archivo. Si esto existe, entonces es una buena apuesta que el archivo esté en esa codificación, pero no es una certeza absoluta. También puede encontrar que el archivo está en una de esas codificaciones, pero no tiene una marca de orden de bytes.

No sé mucho sobre ISO-8859-2, pero no me sorprendería si casi todos los archivos son un archivo de texto válido en esa codificación. Lo mejor que podrá hacer es verificarlo heurísticamente. De hecho, la página de Wikipedia hablando de eso sugeriría que solo el byte 0x7f no es válido.

No hay idea de leer un archivo "tal como está" y aún obtener texto: un archivo es una secuencia de bytes, por lo que debe aplicar una codificación de caracteres para decodificar esos bytes en caracteres.

Fuente por stackoverflow

2

me gustaría añadir que si la cadena está codificada originalmente usando el mal que lo codifica podría ser imposible cambiar a otro sistema de codificación sin errores. La pregunta no indica que la conversión aquí está hecha de una codificación incorrecta para corregir la codificación, pero personalmente tropecé con esta pregunta solo por esta situación, así que solo un aviso para otros también.

Esta respuesta en otra pregunta da una explicación de por qué la conversión no siempre da resultados correctos https://stackoverflow.com/a/2623793/4702806