字节流、字符流、ascii、gb2312、gbk、gb18030、乱码、什么时候使用字节流,什么时候使用字符流,二者区别。分分钟透彻理解。

早先在 Java IO包里面出现的都是字节流,因为数据,无论是硬盘上的还是内存中的,都是字节,都是二进制数据10101的方式进行传输或保存的。

那么为什么后来又出现了个字符流的概念呢?
在我们处理数据的时候,数据的种类有很多,比如dvd,图片,文本,mp3等对于dvd,mp3等都是媒体数据,无论什么数据都是二进制的,0101之类的方式存在的。所以无论什么数据字节流都可以搞定。但是其中有一部分是文本数据,这个是比较常见和常用的,为了方便处理这类数据。单独分离出来个字符流,来处理这类特殊常用的数据类型。

单独分离出来字符流,到底哪方便了呢?
字符流的由来:
(无证可考,我道听途说的。)
想要在计算机里面,识别我们日常生活中的一些数据。计算机是美国人发明的,美国人的生活当中,都是些字母,abcd。。。但是计算机只能识别010101,二进制数。那么就用1010,这个排列组合和字母形成一个一一对应的映射表,比如:a的对应数字就97,等等很多对应关系。想到没有,就是上学时候,说的就是ascii码表。有了这个表,计算机就可以识别美国人的字母和一些标点符号啦,然后,计算机到了中国,为了让计算也能够认识中国的汉字,哎,我们就向美国人学习,也整出来一个表:汉字和1010对应的表,来对应中国的汉字。这张表叫做GB2312,这个表收录了几千个中文汉字和标点符号,但是中文博大精深,几千个哪够啊,所以后来又进行了一次扩容。扩容升级之后叫做GBK,上了两万多的内容,但是还是不够用吧。后面就继续扩容,想想上学时候,你用的新华字典。估计都搬进去啦。然后就有了GB18030,然后呢,上升到国际层面来上说。国际标准化组织就琢磨这事啦。这不行啊。一个国家整个表,这的整多少个码表呢。所以,他们觉得:哎,咱们一共就整一个表,把地球上能用的语言都整进来。然后就把各个国家的文字都给整进来,进行编排,用数字进行编排,弄了个国际性的码表,叫做unicode码表,然后,后期又进行了优化,然后这就是现在常用的utf-8码表的由来。

为啥Unicode要升级为utf-8呢?
Unicode里面无论什么字符,都必须用2个字节表示,一个字节8个二进制位,那么每个都要用16位来表示一个字符,比如a,97,一个8位二进制就够了,用2个浪费空间啦。后期的utf-8就对此做了优化:一个字节够用就用一个,不够用,用2个,还不够,用3个,肯定够了。汉字好像是2个字节,也就是占16位。

乱码的由来:
现在假设我用gbk的编码方式,把“您”这个字给存到电脑上,存起来的数据都是二进制的格式哟,别忘记了哈,这个二进制的数字,是根据gbk这个码表来判断的"您"对应的到底是数字几假设是数字99吧,然后,写到硬盘上。然后,你到另一台电脑上,他的电脑上是utf-8的编码格式,那么在这个utf-8的码表上读99对应的字符,那就不一定是汉字“您”了。所以乱码就由此而产生了。 

为了解决乱码问题,Java出现了字符流。
Java在流技术上,在字节流的基础上,出现了字符流。这个字符流出现的好处有什么呢?他可以在内部融合编码表,也就是说,你读到的这个字节数据,你到底是查的哪个编码表,到底是查gbk的码表,还是查utf-8码表,可以由我们自己来指定,这样我们在处理文字的时候,就可以很方便。这个就是字符流的由来。

简单一句话:字符流的这些对象里面,融合了编码表,只有文字适合编码。

所以,字符流适合处理文字。假如当前我想处理图片,那么就用字节流来处理,为什么?总不至于,你把图片的数据读出来以后,在把数据进行编码表查找,换成文字,一美女图片,你查出来,变成一堆文字,这不合适吧。
通用的是字节流,字符流是基于字节流。

最后就是在 Java的io体系里面一共有四个抽象基类
字节流:InputStream和OutputStream(面向的是计算机,是基础,方便计算机处理)
字符流:Reader和Writer(面向的是人类,方便人类处理文字)

到这里,什么字节流,字符流,gbk,utf-8,乱码,啥的,不都分分钟给你说个明明白白。以后再也不是事儿啦。




你可能感兴趣的:(java)