编码表的由来
计算机只能识别二进制数据,为了方便应用计算机,让它可以识别各个国家的文字,就将各个国家的
文字用数字来表示,并一一对应,形成一张表,这就是编码表。
ASCII:美国标准信息交换码:用一个字节的7位表示
ISO8859—1:拉丁码表。欧洲码表:用一个字节的8位表示
GB2312:中国的中文编码表
GBK:中国的中文码表升级版
Unicode:国际标准码,融合了多种文字。所有文字都用两个字节来表示,java语言使用的就是unicode,一个字符俩字节
utf-8:最多用三个字节来表示一个字符
编码的转换
编码:字符串变成字节数组 String--->byte[]即str.getBytes(charsetName);解码:字节数组变成字符串 byte[]--->String即new String(byte[],charsetName)
String s="你好";
byte[]b=s.getBytes();
System.out.println(Arrays.toString(b));
//打印结果为[-28, -67, -96, -27, -91, -67]说明平台默认编码为utf-8
String s1="你好";
byte[]b1=s1.getBytes("gbk");
System.out.println(Arrays.toString(b1));
//打印结果为[-60, -29, -70, -61]因为GBK是用两个字节表示的字符
由上面的例子说明因为编码表的不同所以保存的数据是不一样的,所以对应的解码表不一致的话就会出现乱码问题。
以下面的例子说明
UTF-8 utf.txt 显示(乱码)
你好 你 -28 -67 -96 写入文本 -28 -67 -96 读取(GBK) -28 -67 浣
好 -27 -91 -67 -27 -91 -67 - 96 -27 犲
-91 -67 ソ
出现这种情况就需要转码
String m="你好";
byte[]p=m.getBytes("utf-8");
String m1=new String(p,"iso8859-1");
System.out.println("m1=="+m1);
//对出现的乱码重新编码解码
byte[]p1=m1.getBytes("iso8859-1");
String m2=new String(p1,"utf-8");
System.out.println(m2);
打印的结果就是 你好
这中情况主要出现在客户端和服务器这种情况,由于tomcat服务器默认编码是iso8859-1.所以客户端使用GBK或UTF-8这种情况就需要在服务器重新编码解码返回到客户端。有人会说问什么不把服务器的编码编程GBK或者UTF-8
这样就不用编码在解码这一过程了,实际上一个服务器可能会有多个工程项目,一个用GBK,一个用UTF-8最后还会乱码,所以上述代码就是一个通用的方式。
流转换编码
对上面的理解透彻落后就可以对流进行操作了
这时候要使用OutputStreamWriter 和InputStreamReader
//以特定编码格式写入
OutputStreamWriter osw1=new OutputStreamWriter(new FileOutputStream("f:\\utf.txt"),"utf-8");
osw1.write("你好");
osw1.close();
//以对应的编码格式读取
InputStreamReader isr=new InputStreamReader(new FileInputStream("f:\\utf.txt"),"utf-8");
char[]buf=new char[1024];
int len=0;
while ((len=isr.read(buf))!=-1) {
System.out.println(new String(buf,0,len));
}
这样就会不会出现乱码问题了。