黑马程序员:字符编码介绍

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

字符编码:

字符流的出现为了方便操作字符

更重要的是加入了编码转换

通过子类转换流来完成
InputStreamReader
OutputStreamWriter
在两个对象进行构造的时候可以加入字符集
提示:除了这两个对象可以加入字符集外,还有PrintStream、PrintWriter,但是它们是打印流,只用于打印

常见编码表:
ASCII:美国标准信息交换码。用一个字节的7位可以表示
ISO8859-1:拉丁码表。欧洲码表。用一个字节的8位表示 前1个高位是1
GB2312:中国的中文编码表 前2个高位都是1
GBK:中国的中文编码表升级,融合了更多的中文文字号,一个文字占两个字节
Unicode:国际标准码,融合了多种文字。所有文字都用两个字节来表示,Java语言使用的就是unicode,16位
UTF-8:最多用三个字节来表示一个字符,1个够就用1个,不够变2个,再不够就3个

编码:字符串变成字节数组(看得懂的变成看不懂的)
String -> byte[]      str.getBytes(charsetName);
解码:字节数组变成字符串(看不懂的变成看得懂的)
byte[] -> String new String(byte[],charsetName);

编码错了,就解不出来了,解码错了,可以对其再次进行编码(这里要注意编码查的是几个字节,比如iso8859-1是1个字节,所以对其再次编码也用iso8859-1的时候读取的也是一个字节,就能读出原编码,若解码错误的值为???,而用utf-8对其编码的时候,一个?号,就会被认为是3个字节,从而???编码后有9个字节,这样就不能通过再此编码解码恢复数据了),再从新解码

示例:
String s = "你好";
byte[] b = s.getBytes("GBK");  //编码
String str = new String(b,"iso8859-1"); //解码,这部解错了,iso8859-1是欧洲码,不支持中文
byte[] newb = str.getBytes("iso8859-1"); //再次编码,因为str原编码是iso8859-1,1个字符占1个字节,对其进行再次编码的时候也是1次差一个字节,所以就可以再次编码
System.out.println(Arrays.toString(newb));
String newstr = new String(b,"GBK"); //解码
System.out.println(Arrays.toString(newstr));

特殊例子:
联通、联系、鞋
在windows中,打开notepad,内容为“联通”,保存关闭后再打开,就会出现乱码
原因是,本身应该通过GBK解码的,结果变成UTF-8解码,为什么会通过UTF-8解码呢?
因为notepad在解码的时候发现编码二进制头是1,GBK开头是1,再接着,第一个字节开头是110,第二个字节开头是10,符合UTF-8的编码规律,所以就用UTF-8解码了,结果就出现了乱码
注:在windows的notepad中,写入的文字都符合UTF-8解码规律的时候才会出现这种情况,只要有一个不符合,就不会出现
通过代码解释原理部分?

String str = "联通";
byte[] arr = str.getBytes("GBK");
for (byte b : arr)
{
	System.out.println(Integer.toBinaryString(b&255)); //b&255,取后八位
}
结果:
11000001
10101010
11001101
10101000


---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------详细请查看: http://edu.csdn.net
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值