将ISO8859字符串转换为UTF8? ÄÖÜ=>为什么?

时间:2011-05-30 10:33:24

标签: java string unicode character-encoding

这段代码有什么问题?我制作了一个ISO8859字符串。因此,大多数ÄÖÜ都是一些krypooutput。没关系。但是如何将它们转换回普通字符(UTF8或其他东西)?

    String s = new String("Üü?öäABC".getBytes(), "ISO-8859-15");

    System.out.println(s);
    //ÃÃŒ?öÀABC => ok(?)
    System.out.println(new String(s.getBytes(), "ISO-8859-15"));
    //ÃÂÃÅ?öÃâ¬ABC => ok(?)
    System.out.println(new String(s.getBytes(), "UTF-8"));
    //ÃÃŒ?öÀABC => huh?

7 个答案:

答案 0 :(得分:7)

new String("Üü?öäABC".getBytes(), "ISO-8859-15");之类的构造几乎总是错误。

您在此处执行的操作是获取String个对象,在平台默认编码中获取相应的byte[]并将其重新解释为ISO-8859-15将其转换回String

如果平台默认编码恰好是ISO-8859-15(或者足够接近这个特定的String,例如ISO-8859-1),那么这是一个无操作(即它没有实际效果)。

在所有其他情况下,最有可能销毁String

如果你尝试“修复”String,那么你可能为时已晚:如果你必须使用特定的编码来读取数据,那么你应该使用它< strong>将二进制数据转换为String数据的点。例如,如果您从InputStream读取,则需要将正确的编码传递给InputStreamReader的构造函数。

尝试解决问题“事后”将是

  1. 更难做到和
  2. 通常甚至不可能(因为使用错误的编码解码byte[]可能是破坏性操作)。

答案 1 :(得分:7)

我希望这能解决你的问题。

String readable = "äöüÄÖÜßáéíóúÁÉÍÓÚàèìòùÀÈÌÒÙñÑ";

try {
    String unreadable = new String(readable.getBytes("UTF-8"), "ISO-8859-15");
    // unreadable -> äöüÃÃÃÃáéíóúÃÃÃÃÃàèìòùÃÃÃÃÃñÃ
} catch (UnsupportedEncodingException e) {
    // handle error
}

String unreadable = "äöüÃÃÃÃáéíóúÃÃÃÃÃàèìòùÃÃÃÃÃñÃ";

try {
    String readable = new String(unreadable.getBytes("ISO-8859-15"), "UTF-8");
    // readable -> äöüÄÖÜßáéíóúÁÉÍÓÚàèìòùÀÈÌÒÙñÑ
} catch (UnsupportedEncodingException e) {
    // ...
}

答案 2 :(得分:4)

String s = new String("Üü?öäABC".getBytes(), "ISO-8859-15"); //bug

所有这些代码都是损坏的数据。它将UTF-16数据转码为系统编码(无论是什么)并获取这些字节,假装它们是有效的ISO-8859-15并将它们转码为UTF-16。

  

然后如何将输入字符串转换为“ÃÃ?Ã?Ã?ABC”正常? (如果我知道该字符串来自ISO8859文件)。

执行此操作的正确方法如下:

byte[] iso859_15 = { (byte) 0xc3, (byte) 0xc3, (byte) 0xbc, 0x3f,
  (byte) 0xc3, (byte) 0xb6, (byte) 0xc3, (byte) 0xa4, 0x41, 0x42,
         0x43 };
String utf16 = new String(iso859_15, Charset.forName("ISO-8859-15"));

Java中的字符串始终是UTF-16。所有其他编码必须使用byte类型表示。

现在,如果您使用System.out输出结果字符串,那可能无法正确显示,但这是一个不同的转码问题。例如,Windows console默认编码与系统编码不匹配。 System.out使用的编码必须与接收数据的设备的编码匹配。您还应该注意确保使用编辑器使用的相同编码reading your source files

要了解字符数据的处理方式因语言而异,请阅读this

答案 3 :(得分:2)

这是一个使用String输出的简单方法(我创建了一个方法来执行此操作):

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 :(得分:1)

Java Strings内部始终存储为UTF16数组(并且在compliation之后作为UTF8存储在类文件中),因此您不能简单地将字符串解释为字节数组。如果要从特定编码的字符串创建字节数组,则必须先转换为此编码:

byte[] b = "Üü?öäABC".getBytes("ISO-8859-15");

System.out.println(new String(b, "ISO-8859-15")); // will be ok
System.out.println(new String(b, "UTF-8")); // will look garbled

答案 5 :(得分:0)

我希望提供扩展字符集,以便将ISO-8859-1中的转换字符串验证为utf-8。

@Test
public void testEnc() throws UnsupportedEncodingException {
    String isoString = "äö";
    String utfString = new String(isoString.getBytes("ISO-8859-1"), "utf-8");
    boolean validConvertion = containsSpecialCharacter(utfString);
    assertTrue(validConvertion);
}

public boolean containsSpecialCharacter(String str) {
    String[] readable = new String[] { "Ã", "Ã", "Ñ", "Ò", "Ó", "Ô", "Õ", "Ö", "×", "Ø", "Ù", "Ú", "Û", "Ü", "Ã", "Þ", "ß",
            "à", "á", "â", "ã", "ä", "å", "æ", "ç", "è", "é", "ê", "ë", "ì", "í", "î", "ï", "ð", "ñ", "ò", "ó", "ô", "õ", "ö",
            "÷", "ø", "ù", "ú", "û", "ü", "ý", "þ", "ÿ" };
    for (String st : readable) {
        if (str.contains(st)) {
            return true;
        }
    }
    return false;
}

答案 6 :(得分:0)

这个解决方案对我有用,我希望能帮到你

id | Q1 | Q2 | Q3
1     5    3    1
2     3    4    1
3     2    3    1