20.1-文件编码
人生最曼妙的风景,竟是内心的淡定与从容。我们曾如此期盼外界的认可,到最后才知道:世界是自己的,与他人毫无关系。
有很多人,因为害怕别人说他孤僻才去社交,让自己出现在声色犬马的群体狂欢中,但真正拥有自我的人,都在用“不合群”的时间让自己变得更加优秀、独立。
文件编码搞不定,文件操作就不行了;
本章总结:
1.为了处理英文字符,产生了ASCII码; ASCII: 1个字节,只编码英文字母和符号
2.为了处理中文字符,产生了GB2312; gb2312: 2个字节,增加了中文汉字和符号
3.为了处理各国字符,产生了Unicode; Unicode: 把所有语言都统一到一套编码里把所有语言都统一到一套编码里,一般是2个字节,生僻字4个字节
4.为了提高Unicode存储和传输性能,产生了UTF-8,它是Unicode的一种实现形式。
utf-8: 可变长编码,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。
文件操作的一些概念
磁盘 :是通过N\S调度顺序来存贮0和1的;
光盘:是通过凹槽与凸起来体现0和1的;凹下去的代表0,突出的代表1多层来增加存贮空间;
IO操作:一般是指文件IO,如果指的是网络IO,都会直接说网络IO;
晶振:是石英晶体谐振器(quartz crystal oscillator)的简称,也称有源晶振、CPU晶体振荡器,它能够产生中央处理器(CPU)执行指令所必须的时钟频率信号,CPU一切指令的执行都是建立在这个基础上的,时钟信号频率越高,通常CPU的运行速度也就越快。
落地:文件存贮操作,存贮到掉电不易失的设备;bit :二进制位, 是计算机内部数据储存的最小单位,11010100是一个8位二进制数。一个二进制位只可以表示0和1两种状态(21);两个二进制位可以表示00、01、10、11四种(22)状态;三位二进制数可表示八种状态(2^3)……
Byte :字节,是计算机中数据处理的基本单位,计算机中以字节为单位存储和解释信息,规定一个字节由八个二进制位构成,即1个字节等于8个比特(1Byte=8bit)。八位二进制数最小为00000000,最大为11111111;通常1个字节可以存入一个ASCII码,2个字节可以存放一个汉字国标码。
字: 在计算机中,一串数码作为一个整体来处理或运算的,称为一个计算机字,简称宇。字通常分为若干个字节(每个字节一般是8位)。在存储器中,通常每个单元存储一个字,因此每个字都是可以寻址的。字的长度用位数来表示。在计算机的运算器、控制器中,通常都是以字为单位进行传送的。
字长:电脑技术中对CPU在单位时间内(同一时间)能一次处理的二进制数的位数叫字长。所以能处理字长为8位数据的CPU通常就叫8位的CPU。同理32位的CPU就能在单位时间内处理字长为32位的二进制数据。
字节和字长的区别:由于常用的英文字符用8位二进制就可以表示,所以通常就将8位称为一个字节。字长的长度是不固定的,对于不同的CPU、字长的长度也不一样。8位的CPU一次只能处理一个字节,而32位的CPU一次就能处理4个字节,同理字长为64位的CPU一次可以处理8个字节。
文件操作
column | 含义 |
---|---|
open | 打开 |
read | 读取 |
write | 写入 |
close | 关闭 |
readline | 行读取 |
readlines | 多行读取 |
seek | 文件指针操作 |
tell | 指针位置 |
open
文件操作,最常用的是 读、写 ;文件访问模式有两种:文本模式和二进制模式;不同模式下,操作函数不尽相同,表现的结果也不一样;
column | 含义 |
---|---|
r | 以读方式打开 |
w | 以写方式打开; |
a | 以追加模式打开 (从 EOF 开始, 必要时创建新文件) |
r+ | 以读写模式打开 |
w+ | 以读写模式打开 (参见 w ) |
a+ | 以读写模式打开 (参见 a ) |
rb | 以二进制读模式打开 |
wb | 以二进制写模式打开 (参见 w ) |
ab | 以二进制追加模式打开 (参见 a ) |
rb+ | 以二进制读写模式打开 (参见 r+ ) |
wb+ | 以二进制读写模式打开 (参见 w+ ) |
ab+ | 以二进制读写模式打开 (参见 a+ ) |
window系统默认的编码方式是UTF-8 ;
windows使用codepage代码页,可以认为每一个代码页就是一张编码表;
文件编码:cp936=gbk 编码
f=open('ls.txt')
----------------------------------------------------------------------------------
<_io.TextIOWrapper name='ls.txt' mode='r' encoding='cp936'>
文件编码类型
ASCII,GBK,GB2312,UNICODE,UTF8
1. 什么是字符编码?
我们用bit(位)来表示每个这种二进制的数,这就是计算机用来表现二进制的方式。而我们在处理数据时,一般并不是按位来进行处理,而是按照字节(byte)来进行处理的,一个字节byte=8bit。
那现在我们面临了第一个问题:如何让人类语言能够被计算机正确理解呢?我们以英文为例(因为计算机是美国佬发明的,所以最开始当然只考虑英文的情况),英文中有英文字母(大小写)、标点符号、特殊符号。如果我们将这些字母与符号给予固定的编号,然后将这些编号转变为二进制用字节来表示,那么计算机明显就能够正确读取这些符号,同时通过这些编号,计算机也能够将二进制转化为编号对应的字符再显示给人类去阅读。所以,基于这种思想,便产生了ASCII码。
2. 【ASCII编码】
ASCII码是人类计算机历史上最早发明的字符集,大家都知道 ,计算机是美国佬发明的,他们只用英文,所以可以说ASCII码是专门为表示英文、数字以及英文标点符号而生。由于英文本身比较简单,就是由26个字母组成,加上0-9十个数字以及一些英文的标点符号。而在计算机中,1byte=8bit,也就是说有从0000000-11111111共2的8次方共256种不同的组合,这些组合已经足够存储所有的这些英文字母、数字以及标点了,所以早期的编码只有ASCII编码。
3. 【GB码】
在中文中光常用的汉字就已经达到了6000多个了,很明显之前的ASCII码已经完全无法满足汉字存储的需求了。怎么办?既然使用ASCII码这样一个字节无法搞定,那么我们自然想到能不能多用1个字节是不能就能搞定了呢?所以,为了满足国内在计算机中使用汉字的需要,中国国家标准总局发布了一系列的汉字字符集国家标准编码,统称为GB码;
GB就是“国标”的意思,即:中华人民共和国国家标准。GB码是面向汉字的编码,包括GB2312(GB2312-80),GBK,GB18030,表示范围从小到大递增,而且基本是向下兼容的。此外经常遇到一种叫做CP936的编码,实际上可以大概看做是GBK。GB系列的编码是为了适应复杂的中文编码而对ASCII码的一种扩充。
4. 【UNICODE标准编码】
假设每种语言都自己搞一套,工作量上去了不说,还为不同编码之间的转换和显示造成了巨大的困难;
为了简化不同编码之间的显示和转换问题,很有必要搞一套统一的编码格式出来。基于这种情况一种新的编码诞生了:Unicode。Unicode又被称为统一码、万国码,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。Unicode支持欧洲、非洲、中东、亚洲(包括统一标准的东亚象形汉字和韩国表音文字)。这样不管你使用的是英文或者中文,日语或者韩语,在Unicode编码中都有收录,且对应唯一的二进制编码;
5. 【UTF-8编码】
UNICODE实际上是使用更多的字节来保存除英文外的其他国家的复杂语言文字,所以对于中文字符这样的文字是非常合适的;
比如,中文汉字的“中”字,用UNICODE编码两个字节就可以这样表示:01001110 00101101,这样一点问题都没有。但如果是英文字母呢?本来英文字母只需要一个字节就可以表示,比如大写字母A,用二进制表示为0100 0001,而用UNICODE的话,就必须用0来补足多出来的一个字节,即表示为00000000 01000001。大家看出问题所在了吗?对了,对于英文来说,UNICODE编码太浪费空间了,足足大了一倍的空间。特别是在网络上进行传输时,这种浪费就极其明显,会大大降低我们的传输效率。
为了解决这个问题,就出现了一些中间格式的字符集,他们被称为通用转换格式,即UTF(Unicode Transformation Format)。而我们最常用的UTF-8就是这些转换格式中的一种。UTF-8编码其实是一种可“变长”的编码格式,即把英文变长为1个字节,而汉字用3个字节表示,特别生僻的还会变成4-6字节。所以如果是传输或存储大量英文的话,UTF编码格式优势非常明显。
6. 不同编码格式和UNICODE之间的转换
为了在不同的编码格式之间进行转换,我们必须对字符进行编码和解码的工作。
任UTF-8,GBK等,通过解码(decode)得到UNICODE,UNICODE通过编码(encode)可以转换成GBK或UTF8等编码(原始8位值)。
u'6'.encode('utf8') -> b'6\xe5\x95\x8a'(16进制表示的原始8位值)
u'6'.encode('gbk') -> b'6\xb0\xa1' (16进制表示的原始8位值)
从上面的例子可以看到6是用一个字节表示的,汉字“啊”在utf8中是用三个字节表示的(gbk中是两个字节),其中\xe5意思就是16进制的e5,代表一个8位二进制:
bin(int('e5', base=16)) -> '0b11100101'。
再比如 “涂” 这个汉字,unicode 为 u'\u6d82'
使用utf8编码时 '\xe6\xb6\x82' 11100110 10110110 10000010 三个8位
使用gbk编码时 '\xcd\xbf' 11001101 10111111 两个8位
要注意的问题
1. 乱码的本质是字符的编码格式与显示字符的环境编码格式不一致引起的。这句话告诉我们要解决乱码问题,我们需要知道两个信息,一个是字符本身是什么编码,另一个就是显示字符的环境编码是什么,两者必须一致,才能显示出正确的内容。
- 由于Unicode编码是标准编码格式,也可以看做是没有任何特定编码格式的“无编码”模式。所以,对于任何Unicode类型编码的字符,打印时python会自动根据环境编码转为特定编码后再显示。