一.解码和编码
解码:就是把能看得懂的转成二进制字节码文件(字节-------->字符)
编码:就是把二进制字节码文件转成能看得懂的文字(字符-------->字符节)
编码表:字典。人们生活中常用的字符与计算机二进制之间的对应关系表
ASCII:美国定义的一张码表。这张码表中只有:数字、字母、符号、拉丁文。用1个字节的最低7位表示数据
生活中的字符 十进制 二进制
a 97 01100001
ISO8859-1:欧洲的一张码表,兼容ASCII,增加了欧洲语言。一个字节表示一个字符,所有8位都表示数据
这张码表中没有未知字符。全部所有数字都有对应的符号
GB2312:兼容ASCII,识别数千中文,2个字节表示一个字符。
GBK:是GB2312的升级版,识别2万多中文,2个字节表示一个字符。
GB18030:是GBK的升级版,包含了大部分的中文,还有少数民族的文字。2个字节
Unicode:世界计算机协会制定通用码表,2个字节表示一个字符。
UTF-8:Unicode升级版。能用1个字节表示的就用1个字节,要用两个字节的就用2个字节,能用3个字节表示的就用3个字节。汉字基本都是3个字节
二.问题
在win7自带的记事本写入"联通"俩个字,再次打开就会乱码,这是为什么呢?
原因是:你保存的时候是ASII格式,再次打开的时候是UTF-8格式。
存储在硬盘上的都是二进制字节码,第一次写入联通时,记事本进行了编码,这时使用的是ASII编码格式。第二次打开的时候,把二进制字节码文件解码成字符串,只不过这次使用的是UTF-8的格式解码。编码和解码使用编码集不同导致的。
解决方法:写入的时候保存为UTF-8的格式。
三.案例
代码实现
package cn.jasonEncodeAndDecode;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
/**
* 乱码会导致丢码,丢失数据
*
* @author Jason
*/
public class Code {
public static void main(String[] args) throws UnsupportedEncodingException {
// 编码
encode();
// 解码
decode();
// 乱码
wrongCode();
}
private static void wrongCode() throws UnsupportedEncodingException {
String s = "你好";
byte[] bytes = s.getBytes("UTF-8");
String string = new String(bytes, "GBK");
// 输出浣犲ソ,由于编码和解码的码表不同导致
System.out.println(string);
// 拨乱反正
byte[] bytes2 = string.getBytes("GBK");
String string2 = new String(bytes2, "UTF-8");
// 输出你好
System.out.println(string2);
}
private static void decode() throws UnsupportedEncodingException {
// String(byte[] bytes, Charset charset) 通过使用指定的 charset 解码指定的 byte
// 数组,构造一个新的 String。
// 把看不懂的转成看的懂的,就是把字节转换成字符
String s = new String(new byte[] { -60, -29, -70, -61 }, "GBK");
// 输出你好
System.out.println(s);
String s1 = new String(new byte[] { -60, -29, -70, -61 }, "UTF-8");
// 输出???,平台默认是GBK,UTF-8是三个字节是一个字符,转换异常
System.out.println(s1);
String s2 = new String(new byte[] { -60, -29, -70, -61 }, "ISO8859-1");
// 输出????,平台默认是GBK,ISO8859-1是一个字节是一个字符,转换异常,欧洲码表没有负数
System.out.println(s2);
}
private static void encode() throws UnsupportedEncodingException {
String s = "你好";
// 使用平台默认的编码集,也就是eclipse的GBK编码[-60, -29, -70, -61]默认GBK
byte[] bytes = s.getBytes();
System.out.println(Arrays.toString(bytes));
// GBK一个字符是两个字节 [-60, -29, -70, -61]
byte[] bytes1 = s.getBytes("GBK");
System.out.println(Arrays.toString(bytes1));
// UTF-8就是[-28, -67, -96, -27, -91, -67],一个字符是3个字节
byte[] bytes2 = s.getBytes("UTF-8");
System.out.println(Arrays.toString(bytes2));
}
}