zoukankan      html  css  js  c++  java
  • Java 字符编码与解码

    1、字符编码的发展历程

      ①、ASCII 码

      因为计算机只认识数字,所以我们在计算机里面的一切数据都是以数字来表示,因为英文字符有限,所以规定使用的字节的最高位是 0,每一个字节都是以 0-127 之间的数字来表示。比如 A 对应 65,a 对应 97。这便是 美国标准信息交换码,ASCII

    1
    2
    3
    String str = new String("Aa");
    byte[] strASCII = str.getBytes("ASCII");
    System.out.println(Arrays.toString(strASCII));//[65, 97]

      

      ②、GB2312 码

      随着计算机在全球的普及,很多国家和地区都把自己的字符引入了计算机,比如汉字。此时发现一个字节能表示的数字范围太小,不能包含所有的中文汉字。那么就规定使用两个字节来表示一个汉字。

      规定:原有的 ASCII 字符的编码保持不变,仍然使用一个字节表示,为了区别一个中文字符与两个 ASCII 码字符相区别。中文字符的每个字节最高位规定为 1(即中文的二进制是负数),这便是 GB2312 编码

    1
    2
    3
    String str = new String("Aa帅锅");
    byte[] strASCII = str.getBytes("GB2312");
    System.out.println(Arrays.toString(strASCII));//[65, 97, -53, -89, -71, -8]

      

      ③、GBK

      由于中国汉字太多,在 GB2312 的基础上增加了更多的中文字符,这种编码是 GBK

    问题:如果只是在中国,那么大家都认识汉字,但是如果是别的国家,而该国家的码表中是没有收录汉字的。那么计算机在显示的时候就为乱码或是别的字符

    解决办法:为了解决各个国家因为本地化字符编码带来的影响,就把全世界所有的字符统一进行编码---Unicode 编码

         此时某一个字符在全世界任何地方显示都是固定的,比如汉字 哥,在任何地方都是以十六进制 54E5 来表示。

         Unicode 的字符编码都占有两个字节

      ④、UTF-8

      是一种针对 Unicode 的可变长度字符编码,又称为 万国码,是 Unicode 的实现方式之一。编码中的第一个字节仍与 ASCII 兼容,这使得原来处理 ASCII 字符的软件无须或只需做少部分修改,即可继续使用。因此,它逐渐成为电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持 UTF-8 编码

    1
    2
    3
    String str = new String("Aa帅锅");
    byte[] strASCII = str.getBytes("UTF-8");
    System.out.println(Arrays.toString(strASCII));//[65, 97, -27, -72, -123, -23, -108, -123]

      

    存储字母、数字:无论什么字符集都占有 1 个字节

    存储汉字:GBK 家族占有 2 个字节。UTF-8 占有 3 个字节

           不能使用单字节的字符集(ASCII/ISO-8859-1)来存储中文

    2、字符的编码和解码

      信息在计算机网络中传输是以字节的形式。那么如何变为字节?这就是编码的过程。那么计算机接收了这个编码,如何让使用者认识呢?那必须要将字节转换为人所识别的字符串形式,这就是解码的过程。

      编码:将字符串转换为 byte 数组

      解码:把 byte 数组转换为 字符串

    注意:①、编码格式和解码格式必须一致,否则乱码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    String str = new String("Aa帅锅");
            //编码操作
            byte[] strByte = str.getBytes("GBK");
            System.out.println(Arrays.toString(strByte));//[65, 97, -53, -89, -71, -8]
             
            //解码操作 
            //注意编码的字符集和解码的字符集格式必须一致(是其扩展字符集也可以),否则会乱码
            //第一种:编码格式为 GBK,解码格式为 ISO-8859-1  那么就会乱码
            String str2 = new String(strByte,"ISO-8859-1");
            System.out.println(str2); //Aa?§??
             
            //第二种:编码和解码格式一致
            String str3 = new String(strByte,"GBK");
            System.out.println(str3); //Aa帅锅

      ②、有时候编码为和解码格式一致了,但是还是乱码,这是因为在数据在传输过程中经过服务器的处理,而这个服务器可能是外国人编写的,那么就会将数据转换为 别的字符格式,那么你如果还是直接转为自己想要的格式是会乱码的。

      解决办法:先获取经过服务器之后的数据还原编码,然后在进行解码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    String str = new String("Aa帅锅");
            //编码操作
            byte[] strByte = str.getBytes("UTF-8");
            System.out.println(Arrays.toString(strByte));//[65, 97, -27, -72, -123, -23, -108, -123]
             
             
            //中间经过了服务器的传输,编码格式转成了 ISO-8859-1
            String str2 = new String(strByte,"ISO-8859-1");
             
            //解码操作  ,此时如果直接进行解码,那么会乱码
            String str3 = new String(str2.getBytes(),"UTF-8");
            System.out.println(str3); //Aa???????
             
            //对于上面的乱码,我们必须先还原服务器之前的编码格式,然后在进行解码。那么就不会乱码
            byte[] strByte2 = str2.getBytes("ISO-8859-1");
            String str4 = new String(strByte2,"UTF-8");
            System.out.println(str4); //Aa帅锅
  • 相关阅读:
    Android Gradle Plugin指南(五)——Build Variants(构建变种版本号)
    文件内容操作篇clearerr fclose fdopen feof fflush fgetc fgets fileno fopen fputc fputs fread freopen fseek ftell fwrite getc getchar gets
    文件操作篇 close creat dup dup2 fcntl flock fsync lseek mkstemp open read sync write
    嵌入式linux应用程序调试方法
    version control system:git/hg/subversion/cvs/clearcase/vss。software configruation management。代码集成CI:Cruisecontrol/hudson/buildbot
    最值得你所关注的10个C语言开源项目
    如何记录linux终端下的操作日志
    CentOS 5.5 虚拟机安装 VirtualBox 客户端增强功能
    sizeof, strlen区别
    C/C++嵌入式开发面试题
  • 原文地址:https://www.cnblogs.com/wangchaonan/p/10700372.html
Copyright © 2011-2022 走看看