使用两个编码之间的getBytes转换字符串

时间:2017-02-28 17:35:04

标签: java unicode encoding utf-8 character-encoding

我有以下代码:

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解释不同吗?

2 个答案:

答案 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")