2009-03-16 6 views
56

Est-ce que quelqu'un sait comment convertir une chaîne de ISO-8859-1 à UTF-8 et de retour en Java?Comment convertir entre ISO-8859-1 et UTF-8 en Java?

Je reçois une chaîne du Web et l'enregistre dans le RMS (J2ME), mais je veux préserver les caractères spéciaux et obtenir la chaîne du RMS mais avec le codage ISO-8859-1. Comment puis-je faire cela?

+0

double possible de [conversion d'encodage en java] (http: // stackoverflow.com/questions/229015/encoding-conversion-in-java) – kamaci

Répondre

87

En général, vous ne pouvez pas faire cela. UTF-8 est capable de coder n'importe quel point de code Unicode. ISO-8859-1 ne peut gérer qu'une infime partie d'entre eux. Ainsi, le transcodage d'ISO-8859-1 en UTF-8 ne pose aucun problème. Si vous revenez de UTF-8 à ISO-8859-1, les «caractères de remplacement» (& # xFFFD;) apparaîtront dans votre texte lorsque des caractères non pris en charge seront trouvés.

transcoder texte:

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

ou

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

Vous pouvez exercer plus de contrôle en utilisant le niveau inférieur Charset API. Par exemple, vous pouvez déclencher une exception lorsqu'un caractère non codable est trouvé ou utiliser un caractère différent pour remplacer le texte.

+1

Pour plus d'informations sur le codage de caractères et pourquoi il n'est pas très logique de passer de UTF-8 à ISO-8859 (ou ASCII ou ANSI d'ailleurs), voir cette explication: http://www.joelonsoftware.com /articles/Unicode.html –

+0

Voici un bon résumé de ce lien: 'Il y a des centaines de codages traditionnels qui ne peuvent stocker que quelques points de code correctement et changer tous les autres points de code en points d'interrogation. Certains encodages populaires du texte anglais sont Windows-1252 (la norme Windows 9x pour les langues d'Europe occidentale) et ISO-8859-1, alias Latin-1 (également utile pour toute langue d'Europe occidentale). Mais essayez de stocker des lettres russes ou hébreu [ou caractères spéciaux] dans ces encodages et vous obtenez un tas de points d'interrogation. UTF 7, 8, 16 et 32 ​​ont tous la bonne propriété d'être en mesure de stocker n'importe quel point de code correctement. » –

+0

Il peut être utile de mentionner que Windows-1252 (Windows Latin 1) étend ISO-8859-1 (Latin officiel 1) en remplissant certains des caractères "Unicode control" 0x80 - 0xbf. Même les navigateurs sur Mac et Linux respectent cela. Donc, à certains endroits, utilisez Windows-1252 à la place. –

6

Si vous avez un String, vous pouvez le faire:

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

Si vous avez un « cassé » String, vous avez fait quelque chose de mal, la conversion d'un String à un String dans un autre encodage est defenetely pas la manière aller! Vous pouvez convertir un String en un byte[] et vice versa (en raison d'un encodage). En Java String s sont codés AFAIK avec UTF-16 mais c'est un détail d'implémentation.

Supposons que vous avez un InputStream, vous pouvez lire dans un byte[] puis le convertir en un String en utilisant

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

ou encore mieux (grâce à erickson) utiliser InputStreamReader comme ça:

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

Si vous avez un InputStream, vous devriez l'inclure dans un InputStreamReader. – erickson

3

Voici un moyen facile avec chaîne de sortie (j'ai créé une méthode pour le faire):

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

Ce qui a fonctionné pour moi: ("Üzüm Bağları" est correct écrit en turque)

Convertir ISO-8859-1 en 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 à 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

Que se passerait-il si vous écrivez le code suivant: 'Chaîne a = new Chaîne (encodedWithUTF8.getBytes (" ISO88591 ")," ISO-8859-1 ")' et 'Chaîne b = nouvelle chaîne (encodedWithUTF8.getBytes (" ISO88591 " ")," UTF-8 ")'? Si la chaîne est en un encodage et que l'on obtient des octets en utilisant l'autre, que se passe-t-il sous le capot? – parsecer

+0

Vous pouvez les essayer et voir les résultats sur votre IDE, et si vous suivez cette URL http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#String (byte [] ,% 20java.nio.charset.Charset) vous verrez la définition de la méthode. Je ne connais pas le détail exact du processus. – webmaster

+1

Si quelqu'un a besoin de cela - je pense que les commandes ci-dessus feraient ce qui suit: 'a' prendrait les octets de' UTF-8', les convertirait en octets 'ISO' et utiliserait alors une table' bytes-> chars' de ' Encodage ISO' pour imprimer la chaîne. Dans le cas de la chaîne 'b', il faudrait utiliser une table' bytes-> chars' de 'UTF-8', donc mapper essentiellement les octets' ISO' selon les règles 'UTF'. 'a' sera imprimé OK même s'il s'agit de' ISO', car Java ne gâche pas le stockage interne des octets. 'b' peut être endommagé parce que certains des caractères' ISO' vont être imprimés comme s'ils appartenaient à l'encodage 'UTF'. – parsecer

0

Apache Commons IO Charsets class peut être utile:

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