几种常见的编码格式
计算机如何表示人类能够理解的符号的?
由于人类语言过多,无法用计算机中一个基本的存储单元 字节
来表示,因而必须要经过拆分或一些翻译工作,才能让计算机理解我们的语言。可以把计算机能够理解的语言假定为英语,其它语言要能够在计算机中使用必须得经过一次翻译,翻译成英语。这个翻译的过程就是编码。只要不是说英语的国家,要使用计算机就必须经过编码。
编码的原因
- 计算机中存储信息的最小单元是 1 个字节,即 8 个 bit,所以能表示的字符范围 0 ~ 255 个。
- 人类要表示的符号太多,无法用 1 个字节来完全表示。
解决这个矛盾必须要有一个新的数据结构 char
,而从 char
到 byte
必须编码。
如何翻译
计算机提供了多种翻译方式,如:ASCII
、ISO-8859-1
、GB2312
、GBK
、UTF-8
、UTF-16
等。他们都可以看作字典,规定了转化规则。
编码格式
ASCII
共 128 个,用 1 个字节的低 7 位表示。ISO-8859-1
在 ASCII 基础上扩展,涵盖了大多数西欧语言字符。但仍然是单字节编码,共能表示 256 个字符。GB2312
双字节编码。GBK
在 GB2312 上进行扩展,并加入更多的汉字。GB2312 编码的汉字可以用 GBK 来解码。UTF-16
定义了 Unicode 字符在计算机中的存取方法,用两个字节来表示 Unicode 的转化格式,采用定长表示,无论什么字符都可以用两个字节表示。两个字节 16 个 bit 所以叫 UTF - 16。JAVA 以 UTF-16 做为内存的字符存储格式。UTF-8
UTF-8 采用变长,不同的字符可以由 1 ~ 6 个字节表示。比 UTF-16 占用小。
在 Java 中需要编码的场景
1、在 I/O 中存在的编码
涉及编码的地方一般都在从字符到字节或从字节到字符的转换上
,而需要这种转换的场景主要是 I/O。
Reader 类是在 Java 中读字符的父类,而 InputStream 类是读字节的父类,InputStreamReader 类就是关联字节到字符的桥梁。负责处理读取字节到字符的转换,面对具体字节到字符的解码实现它又委托 StreamDecoder 去做,在 StreamDecoder 解码过程中必须由用户指定 Charset 编码格式。如果不指定默认使用本地环境中的默认字符集。
涉及 I/O 操作时,只要注意指定统一的编解码 Charset 字符集,一般不会出现乱码问题。不建议使用操作系统默认编码,跨环境可能出现乱码。
2、在内存操作中的编码
除 I/O 涉及编码外,最常用的应该就是在内存中进行从字符到字节的转换,String 表示字符串,提供了到字节的方法,也支持字节到字符的构造函数。
参考
- 《深入分析Java Web技术内幕》(修订版) 许令波 著
发表评论