Java 编码 字符集

时间:2023-03-09 18:48:26
Java 编码 字符集

Java 编码 字符集

@author ixenos

  1. 1.   字符集

a)    字符集建立了两字节Unicode码元序列与使用本地字符编码方式的字节序列之间的映射

b)    为了兼容其它命名,每个字符集都有许多别名,Charset对象的aliases方法可以返回由别名构成的Set对象

i.          Set<String> aliases = charset.aliases();

ii.          for(String alias : aliases){…}

iii.          可以使用别名获得Charset对象:Charset charset =Class.forName(“UTF-8”)

c)

 作者:Jim Liu
链接:https://www.zhihu.com/question/50356029/answer/120608944
来源:知乎
著作权归作者所有,转载请联系作者获得授权。

TL;DR
字符集:收录了若干字符,并且对它们编号索引。
字符编码:将一种字符集当中的编号索引,使用计算机能处理的技术要求和格式(通常是以字节为最小单位)做二进制实现。
----分割线----
GB2312是字符集,也是字符编码,收录量大约几千个字符。
GB18030是字符集,也是字符编码,是对GB2312的一个巨大扩展,收录量大约7万多字符。
以上两个是国标
GBK是微软对GB2312的扩展,兼容GB2312(而GB18030不完美兼容GBK),GBK不是国标。
----分割线----
Unicode是“万国码”字符集,同时它也是一种很朴素的编码,但少有程序会直接用这种编码。
更多程序会使用Unicode Transform Format/UTF编码,比较常见的是UTF-8UTF-16

----分割线----
为什么不支持Unicode而造GB18030?
1、Unicode是全世界用的,受到ISO等制约,并且非常向英语妥协。它不见得是对中文字符最完美的编码方案。打个比方,UTF-8编码方式大多数中文字符需要3字节,而GB18030编码方式大多数中文字符只需要2字节。
2、GB18030是完美兼容GB2312的,这对于中文环境下的遗留系统兼容是非常好的特性。根据*显示,Unicode在1992年才收录中文字符,1993年的Unicode 1.1版本中文收录量是和GB18030差不多的,而GB2312早在80年代就开始普及。并不是我们不兼容Unicode,而是Unicode不兼容我们。对于GB18030而言,他承担了扩展GB2312的作用,不是简单的造*搞标准分化能解释的。Windows在1995年推出了GBK,它是完美兼容GB2312的。在那个年代,互联网还不像今天这么发达,根据不同语言环境选择性价比高的编码方案,还是可以理解的。

d)  本地编码方式模式 不能表示所有的Unicode字符,如果某个字符不能显示,将被转化成“?”

e)  一旦有了字符集,就可以在(Unicode码元的)Java字符串
(编码组成的)字节序列之间进行转换

i.     
编码(动词 encode)Java字符串示例,即转换成byte数组,对应的一个或两个或三个或四个字节代表字符编码(名词)

ii.     
String str =”…”;

iii.     
ByteBuffer buffer = charset.encode(str)
;//使用对应字符集对字符串进行编码,返回ByteBuffer对象

iv.     
byte[] bytes = buffer.array(); //取出该对象中的字节数组

v.     
而要想解码字节序列,自然就需要一个字节缓冲区(ByteBuffer)对象,使用ByteBuffer的静态方法wrap可以将一个字节数组转化成一个ByteBuffer对象的缓冲区

vi.     
byte[] bytes = …;

vii.     
ByteBuffer bbuf = ByteBuffer.wrap(bytes,
offset, length);

viii.     
CharBuffer cbuf = charset.decode(bbuf);//返回CharBuffer对象

ix.     
String str = cbuf.toString();


 扩展阅读

GB18030 根上跟 Unicode 有关系吗?

编码歪传——基础篇

编码歪传——Web篇

编码歪传——番外篇