Java中的编码与解码

在前面学习字符流的时候,我们提到过关于编码的问题,这是个巨坑,一不小心可能就会有乱码出现,但是只要我们弄懂这编码与解码的原理,就能尽量避免踩坑了

何谓编码?何谓解码?

编码,通俗来将就是将我们通俗易懂的数据变成我们不理解的码值,这个过程就称为编码。
比如:我们想写“abc”到硬盘上去,那么实际上硬盘存储的并不是”abc”,而是“abc”对应的码值,所以存储数据的时候是将数据编码然后存储
解码:与编码相反,就是将那些我们不理解的码值查找其对应的字符,我们称这个过程为解码。
比如:存储在硬盘上的“abc”,实际上存储的是其字符值,那么读取数据的时候,首先按照码表查找其对应的字符值然后显示

码表:可以说是编码和解码的规则

ASCII:美国标准信息交换码。用一个字节的7位可以表示。
ISO8859-1:拉丁码表。欧洲码表,用一个字节的8位表示。又称Latin-1(拉丁编码)或“西欧语言”。ASCII码是包含的仅仅是英文字母,并且没有完全占满256个编码位置,所以它以ASCII为基础,在空置的0xA0-0xFF的范围内,加入192个字母及符号,藉以供使用变音符号的拉丁字母语言使用。从而支持德文,法文等。因而它依然是一个单字节编码,只是比ASCII更全面。(所有的编码位置都有对应的码值!所以用该码表编码解码即使出现乱码也不会有信息的丢失!
GB2312:中国的中文编码表。英文用一个字节表示,中文用三个字节表示。
GBK:中国的中文编码表升级,融合了更多的中文文字符号。英文用一个字节表示,中文用三个字节表示。
Unicode: 国际标准码,融合了多种文字。所有文字都用两个字节来表示,Java语言使用的就是unicode。这并不是一种规则,只能是一种标准,按照该标准生成码表应该可以支持各种语言的文字。
UTF-8:英文一个字节,中文三个字节,这就是利用Unicode标准产生的码表之一。
(我们以后接触最多的是iso8859-1、gbk、utf-8)

  • 编码:字符串—–>字节数据

String类的getBytes() 方法进行编码,将字符串,转为对映的二进制,并且这个方法可以指定编码表。
如果没有指定码表,该方法会使用Java编译器设置的编码方式。

  • 解码:字节数组—->字符串

String类的构造函数完成。
String(byte[] bytes) 使用系统默认码表
String(byte[],charset)指定码表
注意:我们使用什么字符集(码表)进行编码,就应该使用什么字符集进行解码,否则很有可能出现乱码(兼容字符集不会)。
并不是所有的乱码都不能还原,也并不是所有的乱码都能还原,尽量使用同一种码表进行编码和解码
下面举例子来解释一下上述语句的含义:

    String str = "中国";
        //利用码表UTF-8编码,我的编译器设置使用UTF-8码表
        byte[] bytes = str.getBytes();
        //利用ISO8859-1解码
        String newStr = new String(bytes,"ISO8859-1");
        //输出必然乱码
        System.out.println(newStr);

但是对于上述输出的乱码,我们是可以还原原来的数据的,因为上面说过ISO8858-1码表虽然不能解码中文,但是其中每个码表值都是有对应字符的,所以说在转换过程中,虽然出现乱码,但是不会丢失原来的数据,只要我们再利用ISO-8859-1码表将newStr编码,然后利用UTF-8码表进行解码即可获取到原来的数据!

    String str = "中国";
        //利用码表UTF-8编码,我的编译器设置使用UTF-8码表
        byte[] bytes = str.getBytes();
        //利用ISO8859-1解码
        String newStr = new String(bytes,"ISO8859-1");
        //输出必然乱码
        System.out.println(newStr);
        //利用ISO8859-1编码
        byte[] b = newStr.getBytes("ISO8859-1");
        //利用码表UTF-8解码得源数据
        String nn = new String(b);
        System.out.println(nn);

但是并不是所有乱码都可以还原,出现乱码都是中文惹的祸,因为英文的编码是兼容的,无论是一个字节还是两个字节,那么如果中文使用的码表中,中文在码表中对应的字符是未知字符,那么就会返回一个未知字符,从而使得信息丢失,那么此时再去还原也不可能得到原来的数据了!所以尽量使用同样的码表去解码编码,否则会有丢失数据的可能!

你可能感兴趣的:(java)