黑马程序员技术交流社区

标题: 编码的一个疑惑 [打印本页]

作者: 早知道    时间: 2013-9-17 20:18
标题: 编码的一个疑惑
本帖最后由 早知道 于 2013-9-20 10:12 编辑

public static void main(String[] args) throws UnsupportedEncodingException {
  String s = "你好";
  byte[] bytes = s.getBytes("gbk");
  String s1 = new String(bytes,"utf-8");//String s1 = new String(bytes,"ISO8859-1");
  byte[] b = s1.getBytes("utf-8");//byte[] b = s1.getBytes("ISO8859-1");
  String s2 = new String(b,"gbk");
  System.out.println(s2);
}
为什么无法得到你好?用注释中的却能得到你好?想破了头,求个好理解的说法。

作者: 麦子609    时间: 2013-9-17 20:37
在Java中,String的getBytes()方法是得到一个操作系统默认的编码格式的字节数组.这个表示在不通Operation System下,返回的东西不一样!

String.getBytes(String decode)方法会根据指定的decode编码返回某字符串在该编码下的byte数组表示,如:
byte[] b_gbk = "中".getBytes("GBK");
byte[] b_utf8 = "中".getBytes("UTF-8");
byte[] b_iso88591 = "中".getBytes("ISO8859-1");
将分别返回"中"这个汉字在GBK、UTF-8和ISO8859-1编码下的byte数组表示,此时b_gbk的长度为2,b_utf8的长度为3,b_iso88591的长度为1.

而与getBytes相对的,可以通过new String(byte[], decode)的方式来还原这个"中"字时,这个new String(byte[], decode)实际是使用decode指定的编码来将byte[]解析成字符串.
String s_gbk = new String(b_gbk,"GBK");
String s_utf8 = new String(b_utf8,"UTF-8");
String s_iso88591 = new String(b_iso88591,"ISO8859-1");
通过打印s_gbk、s_utf8和s_iso88591,会发现s_gbk和s_utf8都是"中",而只有s_iso88591是一个不认识的字符,为什么使用ISO8859-1编码再组合之后,无法还原"中"字呢,其实原因很简单,因为ISO8859-1编码的编码表中,根本就没有包含汉字字符,当然也就无法通过"中".getBytes("ISO8859-1");来得到正确的"中"字在ISO8859-1中的编码值了,所以再通过new String()来还原就无从谈起了.
因此,通过String.getBytes(String decode)方法来得到byte[]时,一定要确定decode的编码表中确实存在String表示的码值,这样得到的byte[]数组才能正确被还原.

有时候,为了让中文字符适应某些特殊要求(如http header头要求其内容必须为iso8859-1编码),可能会通过将中文字符按照字节方式来编码的情况,如:
String s_iso88591 = new String("中".getBytes("UTF-8"),"ISO8859-1"),这样得到的s_iso8859-1字符串实际是三个在ISO8859-1中的字符,在将这些字符传递到目的地后,目的地程序再通过相反的方式String s_utf8 = new String(s_iso88591.getBytes("ISO8859-1"),"UTF-8")来得到正确的中文汉字"中".这样就既保证了遵守协议规定、也支持中文.
作者: javamov    时间: 2013-9-17 20:38
本帖最后由 javamov 于 2013-9-17 20:45 编辑

utf编码是不定长编码,每一个字符的长度从1-6个字节不等。另外,utf编码自带简单的校验功能。一般来讲,英文字母都是用一个字节表示,而汉字使用三个字节。
ISO-8859-1属于单字节编码,
这就是汉子的国标码,专门用来表示汉字,是双字节编码,而英文字母和iso8859-1一致(兼容iso8859-1编码)。
这样byte[] b = s1.getBytes("utf-8");
b的长度为9,
String s2 = new String(b,"gbk"); 这样 gbk编码解析则 是4个半汉字。
作者: 杨增坤    时间: 2013-9-18 11:23
楼主,你好!
如果您的问题解决了,请把您问题的未解决更改为已解决
谢谢合作!





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2