编码之痛(下)一个文件的旅行

来源:互联网 发布:mybaby软件怎么用 编辑:程序博客网 时间:2024/04/29 19:46

博客迁移编码的使用


引:计算机编码不论如何发展,不论计算机的显示器显现出来的东西有多么多姿多彩,在二进制计算机中,底层的编码还是2进制。


一、什么是编码


编码:我们可以理解成一种规则,一种协议,一种大家都遵守的约定。


计算机就是在这种一个又一个的约定下,才把难以识别的2进制变成了多彩的颜色,丰富的表现。


编码在计算机里非常重要,视频需要编码,压缩需要编码,文件需要编码……


二、字符编码


编码多种多样,而我们要讨论就是——字符编码


字符编码常识:

字符编码的基本单位是——字节 (一个字符不同的编码规则可能采用不同数量的字节来编码。如一个汉字,gb2312和gbk是2个字节,utf-8可能是1-3个可变长度….)


无论是硬盘上的文件,内存中的数据,还是通过网络传输过来数据,我们都可以把这些东西叫做 “一团数据” ,姑且先这么叫。这一团数据有的需要编码,有的不需要编码。当你需要把这段数据变成你可以看得懂的一团字符数据的时候——是的,你需要把这段看不懂的数据解码了(字符编码和解码规则基本一样)。所有你在屏幕上看到的东西都是字符编码的(除非你用二进制的方式打开某个文件)。

深入剖析编码来源去处

既然是来源去处,那么来源是什么,去处又是什么?
好的,我将讲述的主题是:进程和流。
注:这里的流知道是——将数据的输入输出看作是数据的流入和流出,这样不管是磁盘文件或者是物理设备(打印机、显示器、键盘等),都可看作一种流的源和目的,视他们为同一种东西,而不管其具体的物理结构。
也就是流如何在不同的进程之间跑来跑去,这里的进程包括单机的不同进程,和两台计算机的不同进程(也就是网络通信)。


三、一个 文件的旅行


当你在硬盘上建立一个文本文件(不论是txt,.cs,.java…)当你保存后,这个文件在硬盘上存在的形式都是以二进制的形式保存在硬盘上。当进程需要读取它的时候你必须调用系统提供的接口,系统把这团数据发给进程,是的这就是文件IO流。进程获取到的数据是什么,依然是一段二进制,这是系统的实现,但是在不同的语言中,对二进制流进行了不同的封装,比如封装成了容易操作的文本流,字符流,字节流等等。我们讨论的字符编码就从字符编码的基础字节流开始。


进程取得字节流后,就可以对取得的数据进行处理,如果需要编码成字符的话,通过特定的编码规则,把字节数据编码成制定的字符数据。编码规则如果正确的话,那么这个文件就被进程成功读取并且编码成字符串了,如果编码规则不对,那么就会出现软件开发中经常遇到的乱码问题。


我们理一下这个过程 ——>

正确的字符数据——>输入进程——>特定编码(如UTF-8)编码成字节——>输入流——> 文件被持久化到硬盘上(有可能是数据库,或者内存中,或者通过网络直接传播等等)——>输出流——> 特定编码(如UTF-8)解码程字符——>输出进程(需要使用这个数据的进程)——>正确的字符数据


在这个过程中:

1如果去掉(持久化过程,把输入流和输出流合并)就是变成一个网络服务器(输入进程)通过网络流传输给用户浏览器(输出进程)然后浏览器通过特定的编码解析传过来的网络流,用户就能看到正确的字符数据了。(网页乱码的常常原因)2如果记事本(输入进程)把用户输入的数据通过特定的编码存到硬盘上,然后记事本(输出进程)在通过特定的编码打开文件,如果编码正确,数据就能正确显示,如果不对就会乱码。(编辑器乱码的常常原因)

在软件开发的时候,很多地方都有手工设置编码的地方,比如Html 的charset=”UTF-8“ ,比如eclipse经常容易乱码,原因就是没有正确的设置文件的编码方式,所以在读取.java文件后,没有用正确的编码方式打开。但是为什么英文没有乱码呢,那是因为,无论是gb2312,gbk,unicode,都和ascll兼容,大概理解就是这些编码的英文编码一样,可以互通,具体可参考我的上一篇博文,编码的发展历史。


如果我们知道输入流的编码,在输出流的时候输入流的编码去解码,那么乱码问题就可以解决了。但是我们知道输入流很少是带有这样的元数据的。所有更多的时候我们需要手工去告诉输出进程(接收流的进程)输入流的编码方式,软件才不会乱码。比如Html 的charset=”UTF-8“就是告诉浏览器,用什么编码去读取流。

各类编码的详细资料请参考我的上篇博文

1 0
原创粉丝点击