python课堂整理18---文件操作(下)
一、b模式,字节方式(二进制的单位),rb wb ab
f = open('test.py', 'rb', encoding = 'utf-8')
报错,因为用了b模式,就不能再指定编码格式了,已经指定读成二进制。
f = open('test.py', 'rb') data = f.read() print(data)
因为test文件内容是以utf-8的格式写入的,一个中文占三个字节
在Windows下,换行符就是 \r\n
#字符串------->转为二进制-------->硬盘
即:‘字符串’------>encode-------->bytes(编码过程)
bytes-------->decode--------->'字符串'(解码过程)
解码:
f = open('test.py', 'rb') data = f.read() print(data.decode('utf8'))
编码:两种方法
x = 'hello' b = bytes(x, encoding = 'utf-8') x.encode('utf8')
例:
f = open('test', 'wb') f.write(bytes('一生所爱', encoding = 'utf-8'))
f = open('test22', 'wb') f.write('我的欢喜'.encode('utf-8'))
注意:r w 其实都是默认成 rt wt ,只能用来打开文本格式,还有图片,视频等格式,所以要用 rb wb ab 这类,转换为二进制,也更适合跨平台。
二、文件操作的其他方法
f = open('a.txt', 'w', encoding = 'utf-8') print(f.closed) #判断文件是否关闭了 print(f.encoding) #取的是文件打开的编码方式(即open里的) f.write('你好') #写入文件用的是open里指定的编码方式 f.flush() #刷新,保存内容到硬盘 f.close()
f = open('b.txt', 'r', encoding = 'utf-8') print(f.tell()) #光标当前所在位置 f.readline() print(f.tell())
为什么是0和8呢,
seek, tell 等光标移动都是以字节为单位
首先刚打开文件,光标在起始位置,所以为 0
读了一行之后,因为utf- 8下,一个中文=3个字节,回车(\r\n)=2个字节,所以,3+3+2=8
############
f.seek(0)
控制光标到0位置
但要注意,中文等于多个字节,比如b.txt中,“你”=3个字节,不能把光标移到2,然后read,会报错,不能拆分中文字节
read(1): 读一个字符
print(f.read(1))
文件的截取
f = open('b.txt', 'r+', encoding='utf-8') f.truncate(10) f.close()
从0位置截取到10位置,按字节数,需要 r+ 或 a+ ,w+不行,会直接覆盖掉,相当于修改了文件,只保留截取的内容
在windows下,换行就是\r\n,但是python自动把\r\n换成了\n,想取消这一自动化操作,用:
f = open('b.txt', 'r', encoding = 'utf8', newline = '') data = f.readlines() print(data) f.close()
三、seek的高级用法
seek后的第二个参数有三种:0, 1, 2
♦ 默认为0,即从起始位置移动光标
with open('b.txt', 'r+', encoding = 'utf-8') as f: f.seek(3, 0) print(f.read()) f.seek(0, 0) f.seek(3) print(f.read())
♦ 第二个参数为 1 时,表示从相对位置(相当于上次位置),要用文件打开的 b 模式(rb)
with open('b.txt', 'rb') as f: f.seek(3) print(f.tell()) f.seek(3, 1) print(f.tell())
♦ 第二个参数为2 时,表示从文件末尾读(倒着seek),要用文件打开的 b 模式(rb),第一个参数需要用负数
with open('b.txt', 'rb') as f: f.seek(-10, 2) data = f.read() print(data.decode('utf-8'))
练习:用seek读日志文件的最后一行
log.txt
2019年7月3日,刘文豪做了一件好事。
2019年7月4日,sb做了一件sb事。
2019年7月5日,大白做了一件好事。
2019年7月6日,家强做了一件好事。
2019年7月7日,傻叉做了一件坏事。
2019年7月8日,小仙女美美地打扮。
2019年7月9日,金灵在学习。
with open('log.txt', 'rb') as f: for i in f: offs = -20 #设置一个偏移量 while True: f.seek(offs, 2) data = f.readlines() if len(data) < 2: offs = offs * 2 if len(data) >= 2: break wan = data[-1] print('日志最后一行为:',wan.decode('utf-8'))
一个奋斗中的产品小白