一、字符编
1.什么是字符编码:将人能识别的字符转换为计算机能识别的01二进制的过程就是字符编码,转换的规则就是字符编码表
2.常用的编码表:ASCII、GBK、Unicode、UTF-8
了解:编码表的发展史
1. ascii(ASCII):字母、数字、英文符号与计算机01标识符的对应关系
思考:如何将128个字符用01完全标签
二进制:11111111 => 255 => 1bytes(1字节) => 8个二进制位
2.中国:研究汉字与计算机01标识符的对应关系:gb2312 => GBK(***) => GB18030
日本:Shift_JIS
韩国:Euc-kr
3.万国码unicode
优点:统一用2Bytes表示所有的字符(任何国家都能使用)
例: a 0000 0000 0010 1010
缺点:
1.浪费存储空间
2.io次数增加,程序运行效率降低(致命)
现在的计算机
内存都是unicode
硬盘都是utf-8
(需要掌握的)
unicode的两个特点
1.兼容万国字符
2.其他国家编码的数据由硬盘读到内存的时候unicode与其他各个国家的编码都有对应关系
(必须掌握的)
数据由内存保存到硬盘
1.内存中的Unicode二进制数字 >>>编码(encode)>>> utf-8格式的二进制数据
硬盘中的数据由硬盘读到内存
1.硬盘中的utf-8格式的二进制数据 >>>解码(decode)>>> 内存中unicode格式的二进制数据
python2
(将py文件按照文本文件读入解释器)默认使用ASCII码(因为再开发python2解释器的时候 unicode还没有盛行)
python3
(将py文件按照文本文件读入解释器)默认使用utf-8
# 思考:unicode与utf-8什么关系
unicode:用2个字节来存储汉字,用2个字节来存储英文字母,占有空间较多,读取效率极高
utf-8:用3-6个字节来存储汉字,用1个字节来存储英文字母,占有空间较少,读取效率低
总结:内存都是按unicode存储数据,硬盘和cpu采用utf-8来存取数据
#“abc你好”
unicode与utf-8采用的是一张unicode编码表,utf-8是unicode编码表体现方式,变长存储数据。
变长优点:(大量数据都是以英文存在,所以utf-8空间更小)传输速度更快
3.编码操作:编码encode()、解码decode()
s = '123呵呵'
n_b = bytes(s, encoding='utf-8')
print(n_b)
b = b'123\xe5\x91\xb5\xe5\x91\xb5'
n_s = str(b, encoding='GBK')
print(n_s)
在清楚原格式是字符串还是二进制时:
# 将u字符串编码成b字符串
print(u'你好'.encode('utf-8'))
# 将b字符串解码成u字符串
print(b'\xe4\xbd\xa0\xe5\xa5\xbd'.decode('utf-8'))
文件头:
# coding:utf-8
1.因为所有的编码都支持英文字符,所以文件头才能够正常生效
python2存数据的时候可以
x = u'上' # 前面加个u 就以unicode格式存数据
print type(x)
print x
基于python2解释器开发的软件,只要是中文,前面都需要加一个u
为了的就是将python2(当你不指定文件头的时候,默认用ASCII存储数据,如果指定文件头那么就按照文件头指定的格式存储)
python3中字符串默认就是unicode格式的二进制数
补充:
1.pycharm终端用的是utf-8格式
2.windows终端用的是gbk
乱码:字符不能够正常显示 编码不一致
(******)
保证不乱码的关键:
文本文件以什么编码编的就以什么编码解码
八位二进制也叫8bit
8bit = 1Bytes
1024Bytes = 1KB
1024KB = 1MB
1024MB = 1GB
1024GB = 1TB
1024TB = 1PB
二、文件操作
1.什么是文件?
操作系统提供给用户操作复杂硬件(硬盘)的简易接口
2.为什么要操作文件?
人或者应用程序需要永久的保存数据
3.如何用?
通过python代码操作文件
r 取消转义
f.open
r'D:\day 06\db.txt',encoding='utf-8'
文件打开的模式
r 只读模式
w 只写模式
a 追加模式
操作文件单位的方式
t 文本文件 t在使用的时候需要指定encoding参数 如果不指定 默认是操作系统的默认编码
b 二进制操作 一定不能指定encoding参数
1.应用程序要想操作计算机硬件 必须通过操作系统来简介的操作
f = open(r'D:\day 06\db.txt',encoding='utf-8') # 向操作系统发送请求 打开某个文件 print(f) # f是文件对象 print(f.read()) # windows 操作系统默认的编码是gbk f.read() # 想操作系统发请求 读取文件内容 f.close() # 告诉操作系统关闭打开的文件 print(f.read())
2.文件上下文操作
with open(r'D:\day 06\db.txt',encoding='utf-8') as f: # f仅仅是一个变量名 print(f) print(f.read()) mode 参数可以不写 不写的话默认是rt 只读文本文件 这个t不写默认就是t with open(r'D:\day 06\db.txt', mode='r' ,encoding='utf-8') as f: print(f.readable()) # 是否可读 print(f.writable()) # 是否可写 print(f.read()) # 一次性将文件内容全部都出 with open(r'D:\day 06\1.jpg', mode='rb') as f: print(f.readable()) # 是否可读 print(f.writable()) # 是否可写 print(f.read()) # 一次性将文件内容全部都出
3.r模式再打开文件的时候 如果文件不在 直接报错(*****)
文件路劲可以写相对路径 需要注意该文件必须与执行文件在同一层文件下
with open(r'db.txt', 'r' ,encoding='utf-8') as f: print(f.readable()) # 是否可读 print(f.writable()) # 是否可写 print('>>>>>:1') print(f.read()) # 一次性将文件内容全部都出 print('>>>>>:2') print(f.read()) # 读完一次之后 文件的光标已经再文件末尾了,再读就没有内容可读了 print(f.readlines()) # 返回的是一个列表 列表中的一个个元素对应的就是文本中一行行的内容 for i in f: print(f) print(f.readline()) # 只读取文件一行 print(f.readline()) print(f.readline()) print(f.readline())
4.w模式:一定要慎用
1.文件不存在的情况下,自动创建该文件 2.当文件存在的情况下 先会清空文件内容再写入 with open(r'jason.txt', 'w' ,encoding='utf-8') as f: print(f.readable()) # 是否可读 print(f.writable()) # 是否可写 print(f.write('鸡哥张江第一大帅逼\n')) print(f.write('鸡哥虹桥第一大帅逼\n')) print(f.write('鸡哥上海第一大帅逼\n')) l = ['鸡哥张江第er大帅逼\n','鸡哥虹桥第一大帅逼\n','鸡哥上海第一大帅逼\n'] print(f.writelines(l))
5.a模式
1.文件不存在的情况下,自动创建该文件 2.当文件存在的情况下 不清空文件内容,文件的光标会移动到文件末尾 with open(r'jason.txt', 'a' ,encoding='utf-8') as f: print(f.readable()) # 是否可读 print(f.writable()) # 是否可写 f.write('鸡哥说:我是大帅逼\n')
4.游标
1. 如何使用游标:游标的相关方法
2. 游标相关的读写操作
3. 根据游标在大文件中取出多个指定位置的部分字节内容
seek(偏移量, 偏移位置)
偏移量以字节为单位
偏移位置:
0 -- 文件开头
1 -- 当前位置
2 -- 文件末尾
在rt模式下 read内的数字 表示的是字符的个数 初次之外,数字表示的都是字节 with open(r'test','r',encoding='utf-8') as f: print(f.read(5)) with open(r'test','rb') as f: res = f.read(10) # 读的是三个字节bytes print(res) print(res.decode('utf-8')) 文件内光标的移动 """ f.seek(offset,whence) offset:相对偏移量 光标移动的位数 whence: 0:参照文件的开头 t和b都可以使用 1:参照光标所在的当前位置 只能在b模式下用 2:参照文件的末尾 只能在b模式下使用 """ with open(r'test','rt',encoding='utf-8') as f: print(f.read(1)) # f.seek(6,0) # seek移动都是字节数 # f.seek(4,0) # seek移动都是字节数 # print(f.read(1)) f.seek(0,0) print(f.read(1)) f.seek(0, 0) print(f.read(1)) f.seek(6,0) print(f.read()) with open(r'test','rb') as f: print(f.read(3).decode('utf-8')) f.seek(0,0) print(f.read(3).decode('utf-8')) f.seek(7,0) print(f.read(1).decode('utf-8')) # f.seek(6,0) # seek移动都是字节数 # f.seek(4,0) # seek移动都是字节数 with open(r'test','rb') as f: print(f.read(3).decode('utf-8')) f.seek(3,1) print(f.read(1)) f.seek(6,0) # seek移动都是字节数 f.seek(4,0) # seek移动都是字节数 with open(r'test','rb') as f: print(f.read()) f.seek(-4,2) print(f.read().decode('utf-8')) with open(r'test','r+',encoding='utf-8') as f: f.seek(3,0) f.write('过')
5.其他模式补充
r+/w+/a+
with open(r'test',mode='r+',encoding='utf-8') as f: print(f.readable()) print(f.writable()) print(f.readline()) f.write('嘿嘿嘿') with open(r'test',mode='w+',encoding='utf-8') as f: print(f.readable()) print(f.writable()) print(f.readline()) f.write('嘿嘿嘿') with open(r'test',mode='r+b') as f: print(f.readable()) print(f.writable()) res = f.read() # print(res.decode('utf-8')) res1 = str(res,encoding='utf-8') print(res1)
6.截断文件
截断前:
with open(r'test','a',encoding='utf-8') as f: f.truncate(6) # 接收的字节的长度 整型 # 保留0~6字节数 后面的全部删除(截断)
截断后:
错误案例:
with open(r'test','a',encoding='utf-8') as f:
f.truncate(4) # 每个汉字所占字节数为3位 如果不是3的倍数 则会出现乱码
7.修改文件
''' 优点:任意时间硬盘上只有一个文件 不会占用过多硬盘空间 缺点:当文件过大的情况下 可能会造成内存溢出 ''' # 修改文件方式1: with open(r'test','r',encoding='utf-8') as f: data = f.read() with open(r'test','w',encoding='utf-8') as f: res = data.replace('jason','egon') f.write(res) ''' 优点:任意时间硬盘上只有一个文件 不会占用过多硬盘空间 缺点:当文件过大的情况下 可能会造成内存溢出 ''' # 修改文件方式2: import os with open(r'test','r',encoding='utf-8') as read_f,\ open(r'base','w',encoding='utf-8') as write_f: for line in read_f: new_line = line.replace('egon','tank') write_f.write(new_line) os.remove(r'test') os.rename('base','test') ''' 优点:内存中始终只有一行内存 不占内存 缺点:在某一时刻硬盘上会同时存在两个文件 '''