"字符集编码" --- "编码字符集" 笔记

ANSI 美国国家标准协会
ANSI编码其实是一个统称,指的是本地操作系统默认的编码
在简体中文系统下,ANSI 编码代表 GB2312 编码,在日文操作系统下,ANSI 编码代表 JIS 编码,在英文系统中,ANSI编码指的是CP1252(类似于ISO-8859-1,只不过在\u0080 到 \u009F 的范围内包含了一些附加字符)

ASCII 美国标准信息交换码(国际标准代码是ISO-646): 用7位二进制数字来表示英文字符.

ISO-8859-1: 对ASCII剩下的128个码位为英文做的扩展.(也叫做Latin-1). 
背景:由于ASCII码只使用了7个二进制位,也就是说一个字节可以表示的256个数字中,它仅使用了0~127这128个码位,剩下的128个码位便可以用来做扩展,用来表示一些特定语言所独有的字符,因此对这多余的128个码位的不同扩展,就形成了一系列ISO-8859-*的标准。例如为英语作了专门扩展的字符集编码标准编号为ISO-8859-1,也叫做Latin-1,为希腊语所作的扩展编号为ISO-8859-7等

UNICODE:用一个大小不超过2的16次方的整数数字为每个字符编号(因此UNICODE是一种编码字符集,而非字符集编码).不够用   (由多家公司发起.)

UCS(UNIVERSAL CHARACTER SET):是一个31位(非32位?)的编码字符集,太多了(由ISO着手制定)

两者(UNICODE和UCS)统一:两者统一了抽象字符集(即任何一个在Unicode中存在的字符,在UCS中也存在),且最靠前的65535个字符也统一了字符的编码。
对于码空间,两者同意以一百一十万为限(约数),Unicode将码空间扩展到了一百一十万,而UCS将永久性的不使用一百一十万以后的码位。
现在再讲Unicode只包含65536个字符是不对的.
Unicode联盟与ISO工作组也同意今后任何的扩展工作两者均保持同步
现在提起Unicode,指代两者均无不妥

编码字符集: 我们常说的Unicode字符集,指的就是这种被分配了整数编号的字符集合.
但是:编码字符集中字符被分配的整数编号,不一定就是该字符在计算机中存储时所使用的值,计算机中存储的字符到底使用什么二进制整数值来表示,是由字符集编码决定的.

字符集编码决定了如何将一个字符的整数编号对应到一个二进制的整数值.(从整数到整数),而编码字符集是从字符到整数.
几乎所有的字符集编码方案中,英文字母的整数编号与其在计算机内部存储的二进制形式都一致.
适用于Unicode字符集的UTF-8编码形式,就将很大一部分字符的整数编号作了变换后存储在计算机中

UTF-8是一种字符集编码,可用于UNICODE字符集(不限于UNICODE,也可以用来给音频,视频等进行编码,只是编出的文件很可能没有播放器支持)
UTF-16,字符集编码,对UNICODE中的前65536个字符编号都不做变换,直接作为计算机存储时使用的值. 因些会使很多人有一种误解认为UNICODE是一种编码.


编码字符集和字符集编码不是一回事,而有的字符集编码又实际上没有做任何事,而是直接把字符编号做为计算机存储时使用的值.GB2312和GBK都是这样:

GB2312最初是指一个编码字符集(包含了ASCII所包含的英文字符,同时加入了6763个简体汉字以及其他一些ASCII之外的符号).GB2312也有自己的编码方案(即直接存储,不做任何转换),只不过这种编码方案一直没有正式的名称,所以现在我们提到GB2312,常常即指这个字符集,也指这种编码方案.
GBK是GB2312的后续标准,添加了更多的汉字和特殊符号,类似的是,GBK也是同时指他的字符集和他的编码.

GBK还是现如今中文Windows操作系统的系统默认编码(这正是几乎所有网页上的,文件里的乱码问题的根源)


在Java中,字符只以一种编码形式存在,那就是UTF-16编码
但“在Java中”到底是指在哪里呢?就是指在JVM中,在内存中,在你的代码里声明的每一个char,String类型的变量中.

这使得一个字符存在的世界分为了两部分:JVM内部和OS的文件系统:在JVM内部,统一使用UTF-16编码, 当这个字符从JVM内部移到外部(即保存为文件系统中的一个文件时),就进行了编码转换,使用了某个具体的编码方案

即所有的编码转换只发生在JVM和OS的交界处 (也即各种输入输出流起作用的地方)

JAVA中的IO两大阵营:面向字符的(Reader, Writer) 面向字节的输入输出流:
面向字节,是指文件在文件系统中的二进制内容和读入JVM内部后的二进制内容一致.(适用于视频,音频文件,或不需要做变换的文件)
面向字符,是指文件的字符在读入JVM前后的表现形式是一样的

所以可以认为,面向字符的Reader, Writer类实际上隐式地为我们做了编码转换: 读入文件时,用默认的编码(即操作系统的默认编码,中文WINDOWS操作系统是GBK,Reader和Writer也只有这么聪明)
将文件解码(即从表示某字符内存地址的二进制数值转换为该字符在编码字符集中的数值)
然后利用GBK字符集和UNICODE字符集(?JVM内部默认的编码字符集)的映射关系找到此字符在UNICODE字符集中的数值,
然后再用UTF-16编码(JVM内部唯一指定官方字符集编码)对该字符编码
从而得到该字符在JVM内存中的二进制地址值

在中文OS中,当我们有一个用UTF-8编码的文件,使用Reader来读的时候,显然会出错.
既然Reader只认得系统的默认编码(GBK),那我们就只能在Reader读文件前将文件转换成GBK编码,
InputSteamReader 和OutputStreamWriter就可以完成这样的功能,这两个类是字节流和字符流之间的适配器,在实例化的时候可以指定编码方式

PrintWriter out=new PrintWriter(new OutputStreamWriter(new FileOutputStream("c:/utf-8.txt"),"UTF-8"));

这里的文件utf-8.txt是用UTF-8编码的,所以我们在实例化OutputStreamWriter时,指定编码方式为"UTF-8",这样在传给Writer之前,系统就会
1. 用UTF-8编码对文件utf-8.txt进行解码,得到字符在GBK字符集中的数值(因为中文OS,默认使用GBK字符集?)
2. 将解码后的文件再用系统默认编码(GBK)进行编码
3. 接下来的事情就可以交给Reader来做了
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值