IO知识Java篇(7) -编码知识

1 字符集与字符编码的关系
(1)字符集(Character set):字符集是一个系统支持的所有抽象字符的集合。

(2)编码(Character Encoding):即在符号集合与数字系统之间建立对应关系.

 

(3)编码字符集Coded character set):即被编码的字符集,是将字符集中的字符与数字建立映射, 通常是由标准组织来制订标准的,例如USASCII,ISO 8859-1,Unicode (ISO 10646-1),以及JIS X0201。

(4)字符编码方案(Character-encoding scheme):编码字符集成员到八位字节(8 bit字节)的映射。编码方案定义了如何把字符编码的序列表达为字节序列。字符编码的数值不需要与编码字节相同,也不需要是一对一或一对多个的关系。原则上,把字符集编码和解码近似视为对象的序列化(字符的持久化存储表示)和反序列化(字符的内存表示),如Unicode编码字符集有UTF-16, UTF-32, UTF-8等存储实现,叫做Unicode转换格式(UTF);而对于GBK编码字符集,它的存储实现也使用编码字符集标准,就是说,GBK编码字符集成员到八位字节(8 bit字节)的映射关系是等于的关系.GBK要转到UTF-8需要先转到Unicode,   再转到UTF-8.

 

(5)Charset(字符集,注意与Character set的概念有区别):术语charset是在RFC2278(http://ietf.org/rfc/rfc2278.txt)中定义的。它是编码字符集和字符编码方案的集合,也就是说,一个字符集是由一个编码字符集和一个相关编码方案组成的.如字符集utf-8,它的编码字符集是Unicode,编码方案是utf-8.

 

(6)jvm中的编码与解码:

编码: 将Unicode表示的字符转换成指定编码方案

解码: 将指定编码方案的字节序列转换成Unicode表示的字符序列


2 在jvm内部,统一使用2个字节(16位)的Unicode编码来表示一个字符char,Unicode编码只是对全球所有字符的映射(但2个字节是不够用的),解析时2个字节2个字节地解析,而其他编码可能灵活地用一个或多个字节对应一个字符,解析时要遵从特有的规则.UTF-16 具体定义了 Unicode 字符在计算机中存取方法。UTF-16 用两个字节来表示 Unicode 转化格式,这个是定长的表示方法,不论什么字符都可以用两个字节表示,两个字节是 16 个 bit,所以叫 UTF-16。UTF-16 表示字符非常方便,每两个字节表示一个字符,这个在字符串操作时就大大简化了操作,这也是 Java 以 UTF-16 作为内存的字符存储格式的一个很重要的原因。

3 utf-8编码中,一个英文字母用一个字节表示,一个中文字符用三个字节表示...

4 new String(str.getBytes(Charset), Charset)

(1)getBytes(Charset)会让JVM进行一次Unicode编码(字符)到指定编码之间的转换。即unicode双字节转换成指定编码集的字节数组,如utf-8会把unicode双字节对应的英文字母转换成单字节,把unicode双字节对应的中文字转换成三个字节.

(2)new String()会用指定的字符集编码将字节数组转换为unicode编码保存在内存.即将字节数组以指定的编码集去解析划分,然后再转换成unicode编码形式的字节数组.如utf-8,则根据原始字节数组的每一位0/1数据,分析出英文字母或中文字,把某个字节划分为一个单位对应一个英文字母,把某三个连续字节划分为一个单位对应一个中文,....,然后再把英文字母或中文字转换成对应的unicode双字节,保存在偶数个元素个数的字节数组中.

5 平台默认的字符集:
如果程序在eclipse中运行,那么使用的是eclipse工程的字符集编码.如果脱离了eclipse的托管独立在操作系统中运行,那么是使用系统平台默认的编码.一般中文平台是使用GBK,英文平台是使用Cp1252

6 面向字节的输入输出流与面向字符的输入输出流
(1)首先,文件中的内容都是以特定编码对应字节的形式保存的,保存到文件中的字节究竟是何种编码,由文件编辑器按某种方法去识别,文件被读进内存,可以按字符读入(需要告诉程序按什么编码去分析字节,所以在底层还是先读取字节,再按指定编码规则将字节序列解码成字符),也可以按字节读入(将字节按顺序读入即可)

(2)如果面向字节,那么从输入流中读取或者从输出流中写入都是以字节为单位的

(3)如果面向字符,那么从输入流中读取或者从输出流中写入都是以字符为单位的,具体每个字符包含多少个字节,要看平台默认的编码格式,如果编码格式不对应,那么字符会变成乱码.

(4)注意Reader和Writer只会使用平台默认的编码方案进行转换,而不能指定转换时使用的编码.

(5)如果用到系统默认的编码以外的文件,就必须采用编码转换:一个字符与字节之间的转换,即:InputStreamReader和OutputStreamWriter,这两个类是字节流和字符流之间的适配器类,承担编码转换的任务.

InputStreamReader:使用指定的 charset 读取字节并将其解码为字符。即由字节数组解析为特定的编码,再转为unicode存储

OutputStreamWriter:可使用指定的 charset 将要写入流中的字符编码成字节。即把unicode表示的字节数组映射为特定编码的字节数组

 

总结:

(1)涉及到字符与字节相互转换时,就跟编码联系上了

(2)字节按指定字符集Charset(编码方案+编码字符集,注意有些情况两者是等于关系,如GBK,或者unicode与utf-16),由Decoder将字节按编码的方案划分成一个个字符对应的字节序列,再转成jvm中的unicode表示(编码字符集)

■GBK -> UNICODE -> UTF-N, 或反之,可以实现转码功能

(3)字符按指定字符集Charset(编码方案+编码字符集,注意有些情况两者是等于关系),由Encoder将字符(由unicode表示),转换成指定的编码方案对应的字节序列

(4)在jvm中,对于编码字符集Unicode与编码方案utf-8,编码解码是存在一定的逻辑对应关系的;而对于字符集GBK与Unicode之间的转换,因为不存在逻辑对应关系,转换时需要根据码表找出对应关系,所以编码和解码的效率上会差点

(5)例:

 Charset charset = Charset.forName("UTF-8"); 
 ByteBuffer byteBuffer = charset.encode(string); 
 CharBuffer charBuffer = charset.decode(byteBuffer);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值