Wie konvertiere ich zwischen ISO-8859-1 und UTF-8 in Java?

73

Weiß jemand, wie man einen String von ISO-8859-1 nach UTF-8 und zurück in Java konvertiert?

Ich erhalte eine Zeichenfolge aus dem Web und speichere sie im RMS (J2ME), aber ich möchte die Sonderzeichen beibehalten und die Zeichenfolge aus dem RMS abrufen, jedoch mit der ISO-8859-1-Codierung. Wie mache ich das?

Michael Myers
quelle
1
Mögliches Duplikat der Codierungskonvertierung in Java
Kamaci

Antworten:

101

Im Allgemeinen können Sie dies nicht tun. UTF-8 kann jeden Unicode-Codepunkt codieren. ISO-8859-1 kann nur einen winzigen Bruchteil davon verarbeiten. Das Transcodieren von ISO-8859-1 nach UTF-8 ist also kein Problem. Wenn Sie von UTF-8 zu ISO-8859-1 zurückgehen, werden "Ersatzzeichen" ( ) in Ihrem Text angezeigt, wenn nicht unterstützte Zeichen gefunden werden.

So transkodieren Sie Text:

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 Sie die untergeordneten CharsetAPIs verwenden. Sie können beispielsweise eine Ausnahme auslösen, wenn ein nicht codierbares Zeichen gefunden wird, oder ein anderes Zeichen als Ersatztext verwenden.

erickson
quelle
1
Weitere Informationen zur Zeichencodierung und warum es zu Recht nicht sinnvoll ist, von UTF-8 auf ISO-8859 (oder ASCII oder ANSI) umzusteigen
JRG-Entwickler
Hier ist eine gute Zusammenfassung von diesem Link:There are hundreds of traditional encodings which can only store some code points correctly and change all the other code points into question marks. Some popular encodings of English text are Windows-1252 (the Windows 9x standard for Western European languages) and ISO-8859-1, aka Latin-1 (also useful for any Western European language). But try to store Russian or Hebrew letters [or special chars] in these encodings and you get a bunch of question marks. UTF 7, 8, 16, and 32 all have the nice property of being able to store any code point correctly.
JRG-Entwickler
Es könnte erwähnenswert sein, dass Windows-1252 (Windows Latin 1) ISO-8859-1 (offizielles Latin 1) erweitert, indem einige der "Unicode-Steuerzeichen" 0x80 - 0xbf eingegeben werden. Sogar Browser unter Mac und Linux respektieren dies. Verwenden Sie daher an einigen Stellen stattdessen Windows-1252.
Joop Eggen
16

Was für mich funktioniert hat: ("üzüm bağları" ist das richtige auf Türkisch geschrieben)

Konvertieren Sie ISO-8859-1 in 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 Sie 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ı"
Bahadir Tasdemir
quelle
Was würde passieren, wenn Sie den folgenden Code schreiben: String a=new String(encodedWithUTF8.getBytes("ISO88591"), "ISO-8859-1")und String b=new String(encodedWithUTF8.getBytes("ISO88591"), "UTF-8")? Wenn sich die Zeichenfolge in einer Codierung befindet und wir mit der anderen Bytes erhalten, was ist dann unter der Haube los?
Parsecer
Sie können sie ausprobieren und die Ergebnisse in Ihrer IDE anzeigen. Wenn Sie dieser URL folgen , wird die Methodendefinition angezeigt. Ich kenne die genauen Details des Prozesses nicht.
Bahadir Tasdemir
1
Wenn jemand das braucht - ich denke , die oben genannten Befehle folgendes tun würde: awürde UTF-8‚s Bytes, wandeln sie in ISOBytes und dann eine Tabelle verwenden , bytes->charsder ISOkodiert , um die Zeichenfolge zu drucken. Im Falle einer Zeichenfolge bwürde eine Tabelle verwendet, in bytes->charsder die UTF-8wesentlichen ISOBytes gemäß den UTFRegeln zugeordnet werden. awird OK ausgedruckt, obwohl dies der ISOFall ist , da Java die innere Speicherung von Bytes nicht durcheinander bringt. bkann beschädigt werden, weil einige der ISOZeichen ausgedruckt werden, als gehörten sie zur UTFCodierung.
Parsecer
Gibt es ein Tool von Drittanbietern, das alle Dateien in einem Repository in UTF-8 konvertieren kann?
Sami
6

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

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

Wenn Sie ein "defekt" haben String, haben Sie etwas falsch gemacht. Die Konvertierung eines Stringin ein Stringanderes in einer anderen Codierung ist definitiv nicht der richtige Weg! Sie können a Stringin a konvertieren byte[]und umgekehrt (bei gegebener Codierung). In Java Stringsind AFAIK mit codiert, UTF-16aber das ist ein Implementierungsdetail.

Angenommen, Sie haben eine InputStream, können Sie eine einlesen byte[]und diese dann in eine StringVerwendung umwandeln

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

oder noch besser (dank erickson) so verwenden InputStreamReader:

InputStreamReader isr;
try {
     isr = new InputStreamReader(inputStream, encoding);
} catch(UnsupportedEncodingException uee) {
    uee.printStackTrace();
}
Johannes Weiss
quelle
1
Wenn Sie einen InputStream haben, sollten Sie ihn mit einem InputStreamReader umschließen.
Erickson
4

Hier ist ein einfacher Weg mit der String-Ausgabe (ich habe eine Methode dafür erstellt):

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";
JLeon90
quelle
1

Regex kann auch gut sein und effektiv verwendet werden (Ersetzt alle UTF-8-Zeichen, die nicht ISO-8859-1durch Leerzeichen abgedeckt sind):

String input = "€Tes¶ti©ng [§] al€l o€f i¶t _ - À ÆÑ with some 9umbers as"
            + " w2921**#$%!@# well Ü, or ü, is a chaŒracte⚽";
String output = input.replaceAll("[^\\u0020-\\u007e\\u00a0-\\u00ff]", " ");
System.out.println("Input = " + input);
System.out.println("Output = " + output);
Pritam Banerjee
quelle
0

Die Apache Commons IO Charsets-Klasse kann nützlich sein:

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

Hier ist eine Funktion zum Konvertieren von UNICODE (ISO_8859_1) in UTF-8

public static String String_ISO_8859_1To_UTF_8(String strISO_8859_1) {
final StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < strISO_8859_1.length(); i++) {
  final char ch = strISO_8859_1.charAt(i);
  if (ch <= 127) 
  {
      stringBuilder.append(ch);
  }
  else 
  {
      stringBuilder.append(String.format("%02x", (int)ch));
  }
}
String s = stringBuilder.toString();
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
    data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                         + Character.digit(s.charAt(i+1), 16));
}
String strUTF_8 =new String(data, StandardCharsets.UTF_8);
return strUTF_8;
}

PRÜFUNG

String strA_ISO_8859_1_i = new String("الغلاف".getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);

System.out.println("ISO_8859_1 strA est = "+ strA_ISO_8859_1_i + "\n String_ISO_8859_1To_UTF_8 = " + String_ISO_8859_1To_UTF_8(strA_ISO_8859_1_i));

ERGEBNIS

ISO_8859_1 strA est = اÙغÙا٠String_ISO_8859_1To_UTF_8 = الغلاف

che.moor
quelle
0

Der einfachste Weg, eine ISO-8859-1-Zeichenfolge in eine UTF-8-Zeichenfolge zu konvertieren.

private static String convertIsoToUTF8(String example) throws UnsupportedEncodingException {
    return new String(example.getBytes("ISO-8859-1"), "utf-8");
}

Wenn wir eine UTF-8-Zeichenfolge in eine ISO-8859-1-Zeichenfolge konvertieren möchten.

private static String convertUTF8ToISO(String example) throws UnsupportedEncodingException {
    return new String(example.getBytes("utf-8"), "ISO-8859-1");
}

Darüber hinaus eine Methode, die eine ISO-8859-1-Zeichenfolge in eine UTF-8-Zeichenfolge konvertiert, ohne den Konstruktor der Klasse String zu verwenden.

public static String convertISO_to_UTF8_personal(String strISO_8859_1) {
    String res = "";
    int i = 0;
    for (i = 0; i < strISO_8859_1.length() - 1; i++) {
        char ch = strISO_8859_1.charAt(i);
        char chNext = strISO_8859_1.charAt(i + 1);
        if (ch <= 127) {
            res += ch;
        } else if (ch == 194 && chNext >= 128 && chNext <= 191) {
            res += chNext;
        } else if(ch == 195 && chNext >= 128 && chNext <= 191){
            int resNum = chNext + 64;
            res += (char) resNum;
        } else if(ch == 194){
            res += (char) 173;
        } else if(ch == 195){
            res += (char) 224;
        }
    }
    char ch = strISO_8859_1.charAt(i);
    if (ch <= 127 ){
        res += ch;
    }
    return res;
}

}}

Diese Methode basiert auf der Verknüpfung von utf-8 mit iso-8859-1 dieser Website. Codierung von utf-8 in iso-8859-1

Ignacio Marín Reyes
quelle