1.一个汉字占用的字节:
一般,GBK编码占用2个字节;UTF-8编码占用3个字节(而英文字符的这两种编码都是1个字节!)
2.UTF-8编码:
就是Unicode字符集的最重要实现方式(另外还有utf-16、utf-32等)之一。UTF-8不是固定字长编码的,而是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
3.Unicode、UTF-8编码、其他编码方式等可参考:
https://www.cnblogs.com/skynet/archive/2011/05/03/2035105.html
https://www.cnblogs.com/hongdada/p/9901246.html
4.Unicode字符集
有ucs-2、ucs-4版本,但一般用ucs-2版本,用两个字节可以表示最常用的六万多个字符,参见:
https://www.zhilian.host/zhidao/gp1njn70d.html
5.UTF-8国际通用为什么还要用GBK?
(1)一个是历史原因,UTF-8编码是逐渐发展起来的,而GBK编码更早;
(2) UTF-8的通用性更好,但比GBK占用更多的字节。
6.乱码:
主要原因是编码和解码的方式不一样;
(1)编码:把字符用编写成字节;
(2)解码:把字节解析成字符。
处理乱码的示例:
//基础:编码以字节的形式存在
//给定字符串
String str = "上海";
//获取平台默认字符集编码的byte数组
byte[] b = str.getBytes();
//展示byte数组
System.out.println(str + "\n默认的编码为:" + Arrays.toString(b));
//以iso8859-1解码,发现是乱码
String s = new String(b, "iso8859-1");
System.out.println("iso8859-1解码为:" + s);
//获取乱码的底层编码
byte[] b1 = s.getBytes("iso8859-1");
System.out.println(s + "与之对应的iso8859-1编码形式:" + Arrays.toString(b1));
//以平台默认的utf-8解码,发现展示正确了~
String s1 = new String(b1, StandardCharsets.UTF_8);
System.out.println(s1);
//处理分析:虽然解码的形式多样、不统一,但只要回到底层的编码,用一致的解码方式去解码就可以正确展示字符串了
7.java 字节流和字符流的区别
java专门把流划分了字节流、字符流。 虽然它们的本质都是字节,但是字符流的api还做了对字节的编码、解码的操作。
8.Base64编码
可参考《计算机网络原理-第6版》275-277页 的base64的出现原因。
大致意思是:最开始SMTP(简单邮件传输协议)只能传输ASCII码编写的文本字符,无法传输图片、视频等二进制文件;
此外,即使是ASCII码,0-32的控制字符(非打印字符)在传输过程可能被特殊处理掉。
后来为解决此问题,MIME(Multipurpose Internet Mail Extensions)多用途因特网邮件扩充标准被提出。
Http(超文本传输协议)本身只能传输ASCII码文本字符,但是后来也支持了MIME。因此,二进制经过Base64编码成一组64ASCII码组成的字符后,Http也能比变相传输二进制文件了。
9.URLEncode编码
专门给URL编码的。url 在定义时,只支持 ASCII字符,所以 url 的发送方与接收方都只能处理 ASCII字符。所以url 中有非ASCII字符、特殊时就需要编码转换。
参考文档:
(1)为什么需要urlEncode - 简书 Http网络基础之URLEncode | 罗晨汛
(2)《计算机网络原理-第6版》第275-277页