黑马程序员_Java基础_IO流_编码表,编码与解码

一,字符流的出现时为了能够操作字符数据,它能操作字符的原因是在其内部加入了编码表。

字节和字符的转换是要通过转换流:InputStreamReaderOutputStreamWriter。这两个流对象时加入了编码表的流对象,当然加入编码表的流对象还有PrintStreamPrintWriter,但是这两个对象只能进行数据的打印,不能读取。

 

二,所谓的编码表就是,机器中二进制编码对应的字符,比如ASCII,用低七位的二进制位表示他们的字符;通常中文操作系统默认的是GBK编码。早期美国最先出来的是ASCII码表,是采用低七位表示。后来欧洲

拉丁语采用八位表示自己的字符,是在七位的基础上添加了一位1,添加后也就是负数的二进制表示,避免了重复;

后来中国也采用这种二进制对应自己的字符做出了自己的编码表,也就是GB2312和后来的GBK(在原来基础上添加了更多的汉字),由于中文比较复杂,就采用两个字节表示一个汉字,也就是16位的二进制数的排列组合。

后来国际上为了统一编码表,做了一个Unicode编码表,表示多种文字,都是用两个字节来表示,Java中就是用的这种编码。最多用3个字节表示一个文字。

 

三,常见的编码表

ASCII:美国标准信息交换码(用一个字节的7位表示)

ISO8859-1:拉丁码表。欧洲码表。(用一个字节的8位表示)

GB2312:中国中文编码表

GBK:中国中文编码表升级,融合了更多的中文文字符号。

Unicode:国际标准码,融合了多种文字.。(所有文字都是使用两个字节表示,java语言使用的就是该码表)

UTF-8:最多用三个字节表示一个文字。

 

如果在编程过程中用UTF-8编码表写的字符文件,在读取的时候查的是GBK编码表则会出现别的汉字,但不是我们想要的结果。

如果编程中指定的是GBK,在读取的时候不小心指定了UTF-8则会出现问号,原因是GBK编码的汉字是两个字符,读取时查找UTF-8编码表,会三个字节三个字节一读取,可能会查不到,所以会显示出问号。

 

需求:输出流使用UTF-8编码向文件中写入数据,使用不同的编码读取文件中的数据观察结果。

          InputStreamReader(InputStream in, String charsetName) 

          创建使用指定字符集的 InputStreamReader

          OutputStreamWriter(OutputStream out, String charsetName) 

          创建使用指定字符集的 OutputStreamWriter 


import java.io.*;
public class UnicodeDemo
{
    public static void main(String[] args) throws IOException {
        //writeDe();
        readDe();
    }
    public static void readDe() throws IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("UTF-8.txt"),"UTF-8");
        //这里不指定编码参数,说明是已默认的GBK编码来读取UTF-8文件的,但是由于UTF-8.txt是用UFT-8编码
        //写出来的,你好是六个字节,所以会以两个字节两个字节的方法到GBK码表中查找是什么字符,,所以出来
        //的不是我们想要的结果。但是如果指定用UTF-8编码表查找的话就会显示出你好。
        char[] b = new char[10];
        int len = 0;
        len = isr.read(b);
        System.out.println(new String(b,0,len));
        isr.close();
    }
    public static void writeDe() throws IOException {
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("UTF-8.txt"),"UTF-8");
        //如果不规定字符编码,则默认的是GBK;
        osw.write("你好");
        osw.close();
    }
}

四,编码与解码

    编码:字符转换成字节;  <比如将文本存储到硬盘中就属于编码>

 

    解码:字节转换成字符;  <比如将硬盘中的存储的文本文件用记事本打开>

 

String  -->  byte[]  str.getBytes()

byte[]  -->  String   new String(byte[])

 

在编码时,如果第一编码用的是GBK但是解码查的是ISO8859-1,那么应该怎么处理呢?

因为在编码的时候用的是GBK编码表编码的,传送到接收方时的是一组数字;而接收方查的是ISO8859-1的表,就会出现乱码,但是因为ISO8859-1的编码表也是两个字节表示一位,所以可以再次用ISO8859-1的表编码一次,这时候返回的还是之前用GBK编码的那一组数字,最后再用GBK解码一次就可以完成。

 

注意:如果在编码时,出现错误,那么解码一定是不能得到想要的结果。但是如果编码正确,解码时出现错误,可以解码后在使用解码时的编码表编码一次,然后在使用正确的编码表解码是可以得到正确结果的。但是这种情况只是使用与GBKISO8859-1之间(我们能涉及到的码表有GBKUTF-8,ISO8859-1三种),如果使用GBK编码,解码时误用了UTF-8,使用上述方法则行不通,因为UTF-8GBK都识别中文造成的。Tomcat服务器使用的是ISO8859-1编码,ISO8859-1不识别中文,所以可以。过程如下:


import java.util.*;
public class EncodeDemo
{
    public static void main(String[] args) throws Exception {
        String s1 = "你好";
        byte[] by = s1.getBytes("GBK");//使用GBK编码
        System.out.println(Arrays.toString(by));
        
        //解码:
        String s2 = new String(by,"ISO8859-1");//使用ISO8859-1解码
        System.out.println(s2);
        //在次编码:
        byte[] by2 = s2.getBytes("ISO8859-1");
        System.out.println(Arrays.toString(by2));
        //再次解码:
        String  s3 = new String(by,"GBK");
        System.out.println(s3);
    }
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值