wake-up-neo.com

Konvertierung von UTF-8 in ISO-8859-1 in Java - Wie bleibt das Einzelbyte erhalten?

Ich versuche, eine in Java kodierte Zeichenfolge in UTF-8 nach ISO-8859-1 zu konvertieren. Angenommen, in der Zeichenfolge "âabcd" "" wird in ISO-8859-1 als E2 dargestellt. In UTF-8 werden sie als zwei Bytes dargestellt. C3 A2 glaube ich. Wenn ich ein getbytes (encoding) und dann eine neue Zeichenfolge mit den Bytes in ISO-8859-1-Codierung erstelle, bekomme ich zwei verschiedene Zeichen. ¢. Gibt es eine andere Möglichkeit, dies zu tun, um den Charakter gleich zu halten, d. H.

57
luckylak

Wenn Sie andere Zeichencodierungen als UTF-16 verwenden, sollten Sie nicht Java.lang.String oder das char-Primitiv verwenden. Sie sollten nur byte[]-Arrays oder ByteBuffer-Objekte verwenden. Dann können Sie Java.nio.charset.Charset verwenden, um zwischen den Kodierungen zu konvertieren:

Charset utf8charset = Charset.forName("UTF-8");
Charset iso88591charset = Charset.forName("ISO-8859-1");

ByteBuffer inputBuffer = ByteBuffer.wrap(new byte[]{(byte)0xC3, (byte)0xA2});

// decode UTF-8
CharBuffer data = utf8charset.decode(inputBuffer);

// encode ISO-8559-1
ByteBuffer outputBuffer = iso88591charset.encode(data);
byte[] outputData = outputBuffer.array();
98
Adam Rosenfield
byte[] iso88591Data = theString.getBytes("ISO-8859-1");

Werde den Trick tun Aus Ihrer Beschreibung scheint es, als ob Sie versuchen, "einen ISO-8859-1-String zu speichern". String-Objekte in Java sind immer implizit in UTF-16 codiert. Es gibt keine Möglichkeit, diese Kodierung zu ändern.

Sie können jedoch die Bytes abrufen, die eine andere Kodierung darstellen (mithilfe der .getBytes () -Methode wie oben gezeigt).

31
Joachim Sauer

Beginnend mit einer Menge von Bytes, die eine Zeichenfolge mit UTF-8 kodieren, erstellt sie eine Zeichenfolge aus diesen Daten und ruft dann einige Byte ab, die die Zeichenfolge in einer anderen Kodierung codieren:

    byte[] utf8bytes = { (byte)0xc3, (byte)0xa2, 0x61, 0x62, 0x63, 0x64 };
    Charset utf8charset = Charset.forName("UTF-8");
    Charset iso88591charset = Charset.forName("ISO-8859-1");

    String string = new String ( utf8bytes, utf8charset );

    System.out.println(string);

    // "When I do a getbytes(encoding) and "
    byte[] iso88591bytes = string.getBytes(iso88591charset);

    for ( byte b : iso88591bytes )
        System.out.printf("%02x ", b);

    System.out.println();

    // "then create a new string with the bytes in ISO-8859-1 encoding"
    String string2 = new String ( iso88591bytes, iso88591charset );

    // "I get a two different chars"
    System.out.println(string2);

dies gibt Strings und die iso88591 Bytes korrekt aus:

âabcd 
e2 61 62 63 64 
âabcd

Ihr Byte-Array wurde also nicht mit der richtigen Kodierung gekoppelt: 

    String failString = new String ( utf8bytes, iso88591charset );

    System.out.println(failString);

Ausgaben

âabcd

(entweder das, oder Sie haben die utf8-Bytes in eine Datei geschrieben und an anderer Stelle als iso88591 gelesen)

7
Pete Kirkham

Das brauchte ich:

public static byte[] encode(byte[] arr, String fromCharsetName) {
    return encode(arr, Charset.forName(fromCharsetName), Charset.forName("UTF-8"));
}

public static byte[] encode(byte[] arr, String fromCharsetName, String targetCharsetName) {
    return encode(arr, Charset.forName(fromCharsetName), Charset.forName(targetCharsetName));
}

public static byte[] encode(byte[] arr, Charset sourceCharset, Charset targetCharset) {

    ByteBuffer inputBuffer = ByteBuffer.wrap( arr );

    CharBuffer data = sourceCharset.decode(inputBuffer);

    ByteBuffer outputBuffer = targetCharset.encode(data);
    byte[] outputData = outputBuffer.array();

    return outputData;
}
1
Kåre Jonsson

Für die Kodierung von Dateien ...

public class FRomUtf8ToIso {
        static File input = new File("C:/Users/admin/Desktop/pippo.txt");
        static File output = new File("C:/Users/admin/Desktop/ciccio.txt");


    public static void main(String[] args) throws IOException {

        BufferedReader br = null;

        FileWriter fileWriter = new FileWriter(output);
        try {

            String sCurrentLine;

            br = new BufferedReader(new FileReader( input ));

            int i= 0;
            while ((sCurrentLine = br.readLine()) != null) {
                byte[] isoB =  encode( sCurrentLine.getBytes() );
                fileWriter.write(new String(isoB, Charset.forName("ISO-8859-15") ) );
                fileWriter.write("\n");
                System.out.println( i++ );
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileWriter.flush();
                fileWriter.close();
                if (br != null)br.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

    }


    static byte[] encode(byte[] arr){
        Charset utf8charset = Charset.forName("UTF-8");
        Charset iso88591charset = Charset.forName("ISO-8859-15");

        ByteBuffer inputBuffer = ByteBuffer.wrap( arr );

        // decode UTF-8
        CharBuffer data = utf8charset.decode(inputBuffer);

        // encode ISO-8559-1
        ByteBuffer outputBuffer = iso88591charset.encode(data);
        byte[] outputData = outputBuffer.array();

        return outputData;
    }

}
0
Frizz1977

Wenn Sie die richtige Kodierung in der Zeichenfolge haben, müssen Sie nicht mehr tun, um die Bytes für eine andere Kodierung zu erhalten.

public static void main(String[] args) throws Exception {
    printBytes("â");
    System.out.println(
            new String(new byte[] { (byte) 0xE2 }, "ISO-8859-1"));
    System.out.println(
            new String(new byte[] { (byte) 0xC3, (byte) 0xA2 }, "UTF-8"));
}

private static void printBytes(String str) {
    System.out.println("Bytes in " + str + " with ISO-8859-1");
    for (byte b : str.getBytes(StandardCharsets.ISO_8859_1)) {
        System.out.printf("%3X", b);
    }
    System.out.println();
    System.out.println("Bytes in " + str + " with UTF-8");
    for (byte b : str.getBytes(StandardCharsets.UTF_8)) {
        System.out.printf("%3X", b);
    }
    System.out.println();
}

Ausgabe:

Bytes in â with ISO-8859-1
 E2
Bytes in â with UTF-8
 C3 A2
â
â
0
Paul Vargas

Zusätzlich zur Antwort von Adam Rosenfield möchte ich hinzufügen, dass ByteBuffer.array() das darunterliegende Byte-Array des Puffers zurückgibt, das nicht unbedingt bis zum letzten Zeichen "getrimmt" ist. Es sind zusätzliche Manipulationen erforderlich, wie in this answer; im Speziellen:

byte[] b = new byte[bb.remaining()]
bb.get(b);
0
Chadi