我有一个用mvn exec运行的程序:java(我的主文件用utf-8编码,我系统的默认字符集是windows-1252)
System.out.println(Charset.defaultCharset()); //print windows-1252
String s = "éàè";
System.out.println(new String(s.getBytes(Charset.forName("UTF-8")))); //OK Print éàè
System.out.println(new String(s.getBytes(Charset.forName("windows-1252")))); //Not OK Print ▒▒▒
根据文档getBytes 使用给定的字符串将字符串编码为字节序列并且String构造函数构造一个新文件,我不明白为什么第一个打印工作正常。使用平台的默认字符集
解码指定的字节数组的字符串所以第一个打印以UTF-8编码,然后使用平台的默认字符集解码,这是windows-1252,这怎么可能?它无法使用平台charset windows-1252解码编码的utf-8字节数组。
第二次印刷是错误的,我不明白为什么。由于我的文件是用utf-8编码的,平台字符集是windows-1252,我打算用windows-1252字符集对字符串进行编码,所以我调用s.getBytes(Charset.forName(" windows-1252&#34) ;))然后创建一个具有前一个结果的字符串,但它没有工作
答案 0 :(得分:3)
String
值éàè
以UTF-8编码为字节八位字节0xC3 0xA9 0xC3 0xA0 0xC3 0xA8
。解释为Windows-1252的相同字节八位字节是字符串值éÃ<nbsp>è
(其中<nbsp>
是非中断空格字符,Unicode代码点U+00A0
)。< / p>
在第一个示例中,您将String
转换为上述UTF-8字节,然后使用Windows-1252而不是UTF-8将字节转换回String
。因此,您应该获得String
的新éÃ<nbsp>è
值,而不是éàè
。然后,您将String
写入控制台,因此使用Windows-1252将其编码回字节八位字节0xC3 0xA9 0xC3 0xA0 0xC3 0xA8
,如果éÃ<nbsp>è
(或类似于它),则应显示为éàè
控制台按原样显示字节。另一方面,如果控制台配置为UTF-8,那么当解释为UTF-8时,这些字节将显示为String
。
在第二个示例中,由于您使用Windows-1252进行编码和解码,并且Windows-1252支持所讨论的特定字符,因此最终应使用原始éàè
值{{1在将其写入控制台之前。如果使用Windows-1252将String
编码为字节,并且控制台配置为UTF-8,那么为什么您看不到显示的éàè
是有意义的。 String
值éàè
在Windows-1252中编码为字节八位字节0xE9 0xE0 0xE8
,它不是有效的UTF-8字节八位字节序列。
简而言之,当您的控制台配置为将传出字节解释为UTF-8时,您所看到的行为会发生,但您没有将正确的UTF-8编码字节作为输出。