我有以下代码:
String s0="Përshëndetje botë!";
byte[] b1=s0.getBytes("UTF8");
byte[] b2=s0.getBytes("ISO8859_1");
String s0_utf8=new String(b1, "UTF8"); //right encoding, wrong characters
//String s0_utf8=new String(b1, "ISO8859_1"); //wrong encoding, wrong characters
String s0_iso=new String(b2, "UTF8"); //wrong encoding; outputs right characters
//String s0_iso=new String(b2, "ISO-8859-1"); //right encoding; if uncommented, outputs damaged characters
System.out.println("s0_utf8: "+s0_utf8); //
System.out.println("s0_iso: "+s0_iso);
因此,使用"Përshëndetje botë!"
和UTF8
将字符串ISO-8859-1
转换为字节,然后使用相应的编码将这些字节转换回Unicode字符。这里只显示一个正确的字符:如果我们使用ISO8859_1
将原始字符串编码为字节,并使用UTF-8
对其进行解码。所有其他情况都会导致错误的字符。
String s0="P\u00ebrsh\u00ebndetje bot\u00eb!";
byte[] b1=s0.getBytes("UTF8");
byte[] b2=s0.getBytes("ISO8859_1");
String s0_utf8=new String(b1, "UTF8"); //right encoding; outputs right characters
//String s0_utf8=new String(b1, "ISO8859_1"); //wrong encoding, wrong characters
String s0_iso=new String(b2, "UTF8"); //wrong encoding; outputs wrong characters
//String s0_iso=new String(b2, "ISO-8859-1"); //right encoding; if uncommented, outputs damaged characters
System.out.println("s0_utf8: "+s0_utf8); //
System.out.println("s0_iso: "+s0_iso);
这里有两种情况,当显示正确的单词时:当使用相同的编码对字符串进行编码和解码时。
我不明白这里发生了什么。怎么可能? Unicode的字符表示有什么区别?为什么这对用iso-decode与utf8一起工作?结果字符串不应该与原始字符串完全不同,因为utf的字节可能被utf8解释不同吗?
答案 0 :(得分:1)
我的猜测是字符串从一开始就是错误的,因为你的Java源文件是用编码A编码的,编译器用编码B读取它。这就解释了为什么当你使用escape时问题不会发生序列而不是重音。
关于
//String s0_iso=new String(b2, "ISO-5589-1"); //right encoding; if uncommented, outputs damaged characters
不,它不是正确的编码。 5589 != 8859
。
答案 1 :(得分:0)
This回答真的帮助我理解了发生了什么。
在第一种情况:
中 String s0="Përshëndetje botë!";
s0
位于ISO8859_1
;
b1
:以UTF-8 获取字节,
b2
:获取ISO8859_1中的字节。
IDEA错误地转换ë
字符=> Përshëndetje botë!
String s0_iso=new String(b2, "UTF8");
将字符串转换为IDEA的编码并正确打印。
String s0_iso=new String(b2, "ISO-8859-1");
不会更改原始字符串 => Përshëndetje botë!
当字符串转换为外部编码(UTF-8)时,麻烦就来了:
String d=new String(b1, "UTF8");
=>的 Përshëndetje botë!
强>
String b=new String(b1, "ISO8859_1");
=>的 Përshëndetje botë!
强>
我仍然不完全确定在这两种情况下发生了什么,但是
d.equals("Përshëndetje botë!")
是true
。
我的猜测是当字符串在utf-8中编译时(默认)编译器将s0
中的字符解释为好像它们已经在UTF-0
中并且没有真正的转换发生;由于UTF-8
中没有这样的字符,因此字符变坏了。在构造d
字符串时,同样会发生同样的情况,但是通过代码本身,所以字符的处理就好像它们已经在UTF-8
中一样,然后被推送到同一个{{1 }}。但它们应该首先从UTF-8
解码,然后才编码为ISO8859_1
,这就是输出错误的原因。
第二种情况:
UTF-8
原始字符串已完全位于String s0="P\u00ebrsh\u00ebndetje bot\u00eb!";
中。因此显示它的问题会更少。
UTF-8
不会更改原始字符串; String d = new String(b1, "UTF8")
是d.equals(s0)
=>的 true
强>
Përshëndetje botë!
将原始String p =new String(b1, "ISO8859_1")
字符串转换为UTF-8
=>的 ISO8859_1
强>
Përshëndetje botë!
是p.equals("Përshëndetje botë!")
。
不确定这里发生了什么以及为什么最后一个正确地获取所有字符:
true
=>的 String s0_iso=new String(b2, "UTF8")
强>
P�rsh�ndetje bot�
=>的 String s0_iso=new String(b2, "ISO-8859-1")
强>