2009-03-16 4 views
56

Kann jemand eine Zeichenfolge von ISO-8859-1 nach UTF-8 und zurück in Java konvertieren?Wie konvertiere ich zwischen ISO-8859-1 und UTF-8 in Java?

Ich bekomme eine Zeichenfolge aus dem Internet und speichern sie in der RMS (J2ME), aber ich möchte die speziellen Zeichen erhalten und die Zeichenfolge aus dem RMS, aber mit der ISO-8859-1-Codierung. Wie mache ich das?

+0

möglich Duplikat [Encoding Umwandlung in java] (http: // Stackoverflow.com/questions/229015/encoding-conversion-in-java) – kamaci

Antwort

87

Im Allgemeinen können Sie dies nicht tun. UTF-8 kann jeden Unicode-Codepunkt codieren. ISO-8859-1 kann nur einen winzigen Teil von ihnen verarbeiten. Die Transcodierung von ISO-8859-1 nach UTF-8 ist also kein Problem. Wenn Sie von UTF-8 nach ISO-8859-1 zurückgehen, werden "Ersatzzeichen" (& # xFFFD;) in Ihrem Text angezeigt, wenn nicht unterstützte Zeichen gefunden werden.

Text umcodieren:

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

oder

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

Sie können mehr Kontrolle ausüben, indem der unteren Ebene Charset APIs. Sie können beispielsweise eine Ausnahme auslösen, wenn ein nicht codierbares Zeichen gefunden wird, oder ein anderes Zeichen als Ersatztext verwenden.

+1

Weitere Informationen zur Zeichencodierung und warum es zu Recht nicht sinnvoll ist, von UTF-8 zu ISO-8859 (oder ASCII oder ANSI) zu wechseln, finden Sie in dieser Erklärung: http://www.joelonsoftware.com /articles/Unicode.html –

+0

Hier ist eine gute Zusammenfassung von besagtem Link: 'Es gibt Hunderte von traditionellen Codierungen, die nur einige Codepunkte korrekt speichern können und alle anderen Codepunkte in Fragezeichen ändern. Einige beliebte Kodierungen von englischem Text sind Windows-1252 (der Windows 9x Standard für westeuropäische Sprachen) und ISO-8859-1, auch bekannt als Latin-1 (auch nützlich für jede westeuropäische Sprache). Versuchen Sie jedoch, russische oder hebräische Buchstaben [oder Sonderzeichen] in diesen Kodierungen zu speichern, und Sie erhalten eine Reihe von Fragezeichen. UTF 7, 8, 16 und 32 haben alle die Eigenschaft, jeden Codepunkt korrekt speichern zu können. –

+0

Erwähnenswert ist, dass Windows-1252 (Windows Latin 1) ISO-8859-1 erweitert (offizielles Latein 1)) indem Sie einige der "Unicode Control" Zeichen 0x80 - 0xbf ausfüllen. Sogar Browser unter Mac und Linux respektieren das. Verwenden Sie stattdessen an einigen Stellen Windows-1252. –

6

Wenn Sie eine String haben, können Sie das tun:

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

Wenn Sie ein ‚gebrochen‘ String haben, haben Sie etwas falsch, ein String zu einem String in einer anderen Kodierung Umwandlung ist defenetely nicht der richtige Weg gehen! Sie können eine String in eine byte[] konvertieren und umgekehrt (bei einer Codierung). In Java sind String s AFAIK-codiert mit UTF-16, aber das ist ein Implementierungsdetail.

Sagen Sie bitte eine InputStream haben, können Sie in einem byte[] lesen und dann, dass

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

oder noch besser (dank Erickson) verwenden InputStreamReader wie die Verwendung zu einem String konvertieren:

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

Wenn Sie einen InputStream haben, sollten Sie ihn mit einem InputStreamReader umschließen. – erickson

3

Hier eine einfache Möglichkeit, mit String ausgegeben (habe ich eine Methode, dies zu tun):

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

, die für mich gearbeitet: ("üzüm Baglari" ist die korrekte geschrieben in Türkisch)

Convert ISO-8859-1 auf 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ı" 

konvertieren UTF-8 in 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

Was würde passieren, wenn Sie den folgenden Code schreiben würden: 'String a = new String (encodedWithUTF8.getBytes (" ISO88591 ")," ISO-8859-1 ")' und 'String b = new String (encryptedWithUTF8.getBytes (" ISO88591 ")," UTF-8 ")'? Wenn die Zeichenfolge in einer Kodierung ist und wir Bytes mit der anderen Kodierung erhalten, was passiert unter der Haube? – parsecer

+0

Sie können sie ausprobieren und die Ergebnisse in Ihrer IDE sehen, und wenn Sie dieser URL folgen http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#String (byte [] ,% 20java.nio.charset.Charset) sehen Sie die Methodendefinition. Ich kenne das genaue Detail des Prozesses nicht. – webmaster

+1

Wenn jemand das braucht - ich denke, die obigen Befehle würden folgendes tun: 'a' würde' UTF-8''s Bytes nehmen, sie in 'ISO' Bytes umwandeln und dann eine Tabelle' bytes-> chars' von 'verwenden ISO'-Codierung, um die Zeichenfolge auszudrucken. Im Falle des Strings "b" würde er eine Tabelle "bytes-> chars" von "UTF-8" verwenden und daher im Wesentlichen "ISO" -Bytes gemäß den "UTF" -Regeln abbilden. 'a' wird ausgedruckt, OK, obwohl es' ISO' ist, weil Java seine interne Speicherung von Bytes nicht durcheinander bringt. "b" kann beschädigt werden, weil einige der ISO-Zeichen ausgedruckt werden, als gehörten sie zur UTF-Codierung. – parsecer

0

Apache Commons IO Charsets class kann nützlich sein:

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