java里关于String的编码与解码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java里关于String的编码与解码相关的知识,希望对你有一定的参考价值。

参考技术A public
byte[]
getBytes(String
charsetName)
使用指定的字符集将此String编码为byte序列,结果存在一个byte数组中
public
String(byte[]
bytes,
String
charsetName)
通过使用指定的
charset
解码指定的
byte
数组,构造一个新的
String。
在网络传输中,信息都是以字节序列的方式传输的。所以,发送方的String要按照某种编码方式(如UTF-8,GBK)编码为字节序列,在网络中传输后,接收方取得这个字节序列,按照相同的编码方式将字节序列解码为String。
请看下面的代码片段:
String
name
=
"张三";
byte[]
b1
=
name.getBytes("UTF-8");
String
name1
=
new
String(b1,
"UTF-8");
//编码解码相同,正常显示
System.out.println(name1);
String
name2
=
new
String(b1,
"GBK");
//编码解码不同,乱码
System.out.println(name2);
byte[]
b2
=
name.getBytes("GBK");
String
name3
=
new
String(b2,
"GBK");
//编码解码相同,正常显示
System.out.println(name3);
String
name4
=
new
String(b2,
"UTF-8");
//编码解码不同,乱码
System.out.println(name4);
至于你的那个情况,要先用gbk编码,然后再用utf-8解码才能获得正常的字符串,我估计是因为
1.传输过来的字节码是用utf-8编码的,假设字节码为b。
2.你获得的那个字符串,假设为s,是用gbk对b进行解码获得的字符串,所以是乱码。
3.你使用gbk对s进行编码,用gbk解码之后再编码,于是获得了原来的b。
4.你使用utf-8解码,所以获得了正常的字符串。
简单的说:
b
->
(gbk解码)
->
乱码
->
[此处开始是你做的](gbk编码)
->
b
->
(utf-8解码)
->
正常字符串
研究完编码收获会不小的,对以后理解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帅锅

  


以上是关于java里关于String的编码与解码的主要内容,如果未能解决你的问题,请参考以下文章

关于乱码

关于前台js编码后台java解码

关于PHP二进制安全的解释

Python8_关于编码解码和utf-8

数据的编码和解码--java例子

请问一个关于URL中汉字编码解码的问题