一丶文件处理的b模式
b模式都是以二进制为单位
1.b模式的使用
with open('1.mp4',mode='rb') as f: data=f.read() print(type(data)) # 输出结果为:<class 'bytes'> with open(r'f.txt',mode='wb') as f: f.write('你好hello'.encode('utf-8')) f.write('哈哈哈'.encode('gbk'))# 在b模式下写入文件的只能是bytes类型
总结:
1、在操作纯文本文件方面t模式帮我们省去了编码与解码的环节,b模式则需要手动编码与解码,所以此时t模式更为方便
2、针对非文本文件(如图片、视频、音频等)只能使用b模式
# 文件拷贝工具 src_file=input('源文件路径>>: ').strip() dst_file=input('源文件路径>>: ').strip() with open(r'{}'.format(src_file),mode='rb') as f1, open(r'{}'.format(dst_file),mode='wb') as f2: # res=f1.read() # 内存占用过大 # f2.write(res) for line in f1: f2.write(line)
2.操作文件的方法
# 读操作 # 1.f.read()一次性读出所有内容,读完内容指针在结尾 with open('a.txt','rt',encoding='utf-8') as f: print(f.read()) # 2.f.readline()一次只读一行,读完一行光标移动到下一行头部 with open('a.txt','rt',encoding='utf-8') as f: res1=f.readline() res2=f.readline() print(res2) # 3.f.readlines()读取每行内容放到列表当中,在一次性读出 with open(r'a.txt',mode='rt',encoding='utf-8') as f: res=f.readlines() print(res) # 强调: # f.read()与f.readlines()都是将内容一次性读入内存,如果内容过大会导致内存溢出,若还想将内容全读入内存
# 循环读取文件 # 方式一:以行为单位读,当一行内容过长时会导致一次性读入内容的数据量过大 with open('a.txt','rt',encoding='utf-8') as f: for line in f: print(line) # 方式二 with open('a.txt','rb') as f: while True: res=f.read(1024) # 每次只读取1024字符 if len(res) == 0: break print(len(res))
# 写相关操作 #f.write() f.writelines()将列表内的元素依次写入 with open('a.txt','wt',encoding='utf-8') as f: f.write('1111 222 3333 ') #针对文本模式的写要自己写换行符 l = ['11111 ', '2222', '3333', 4444] # for line in l: # f.write(line) f.writelines(l)#writelines完成了上面for循环的功能 with open('a.txt','wb') as f: l = [ '1111aaa1 '.encode('utf-8'), '222bb2'.encode('utf-8'), '33eee33'.encode('utf-8') ] # 补充1:如果是纯英文字符,可以直接加前缀b得到bytes类型 # l = [ # b'1111aaa1 ', # b'222bb2', # b'33eee33' # ] # 补充2:'上'.encode('utf-8') 等同于bytes('上',encoding='utf-8') # l = [ # bytes('上啊',encoding='utf-8'), # bytes('冲呀',encoding='utf-8'), # bytes('小垃圾们',encoding='utf-8'), # ] f.writelines(l) # f.flush 将要写的内容马上存入硬盘 # with open('h.txt', mode='wt',encoding='utf-8') as f: # f.write('哈') # f.flush()
with open('h.txt', mode='wt',encoding='utf-8') as f: print(f.readable())# 文件是否可读 print(f.writable())# 文件是否可读 print(f.encoding)# 如果文件打开模式为b,则没有该属性 print(f.name) print(f.closed)# 文件是否关闭
二丶控制内指针的移动
'''指针移动的单位都是以bytes/字节为单位 只有一种情况下特殊:t模式下的read(n),n代表的是字符个数''' with open('a.txt',mode='rt',encoding='utf-8') as f: data=f.read(3) # 读取3个字符 with open('a.txt',mode='rb') as f: data=f.read(3) # 读取3个Bytes # f.seek(指针移动的字节数,模式控制): # 0: 默认的模式,参照物是文件开头位置 f.seek(9,0) # 9 f.seek(3,0) # 3 # 1: 参照物是当前指针所在位置 f.seek(9,1) # 9 f.seek(3,1) # 12 # 2: 参照物是文件末尾位置,应该倒着移动 f.seek(-9,2) # 3 f.seek(-3,2) # 9 # 强调:其中0模式可以在t或者b模式使用,而1跟2模式只能在b模式下用 # f.tell() # 获取文件指针当前位置
2.1 0模式详解
with open('a.txt',mode='rb') as f: f.seek(4,0) # 4 print(f.tell()) res=f.read() print(res.decode('utf-8'))
2.2 1模式详解
with open('a.txt',mode='rb') as f: f.seek(3, 1) print(f.tell()) #3 f.seek(4, 1) print(f.tell()) #7
2.3 2模式的详解
with open('a.txt',mode='rb') as f:
f.seek(0,2) print(f.tell()) # 9 f.seek(-3,2) # 参照文件末尾往前移动了3个字节 print(f.read().decode('utf-8')) # 旦
2.4 f.seek的应用(tail -f accsee.log程序讲解)
# 追写文件内容的程序test.py with open(r'access.log', 'at', encoding='utf-8') as f: f.write('202003111112 egon转账200w ') # 监测追写内容的程序tail.py import time with open(r'access.log', 'rb') as f: f.seek(0, 2) while True: line = f.readline() if len(line) == 0: time.sleep(0.3) else: print(line.decode('utf-8'), end='')
三丶文件的修改
# 文件a.txt内容如下 张一蛋 山东 179 49 12344234523 李二蛋 河北 163 57 13913453521 王全蛋 山西 153 62 18651433422 # 执行操作 with open('a.txt',mode='r+t',encoding='utf-8') as f: f.seek(9) f.write('<妇女主任>') # 文件修改后的内容如下 张一蛋<妇女主任> 179 49 12344234523 李二蛋 河北 163 57 13913453521 王全蛋 山西 153 62 18651433422 # 强调: # 1、硬盘空间是无法修改的,硬盘中数据的更新都是用新内容覆盖旧内容 # 2、内存中的数据是可以修改的
3.1 文件修改方式一
# 实现思路:将文件内容发一次性全部读入内存,然后在内存中修改完毕后再覆盖写回原文件 # 优点: 在文件修改过程中同一份数据只有一份 # 缺点: 会过多地占用内存 with open('db.txt',mode='rt',encoding='utf-8') as f: data=f.read() with open('db.txt',mode='wt',encoding='utf-8') as f: f.write(data.replace('kevin','SB'))
3.2 文件修改方式二
# 实现思路:以读的方式打开原文件,以写的方式打开一个临时文件,一行行读取原文件内容,修改完后写入临时文件...,删掉原文件,将临时文件重命名原文件名 # 优点: 不会占用过多的内存 # 缺点: 在文件修改过程中同一份数据存了两份 import os with open('db.txt',mode='rt',encoding='utf-8') as read_f, open('.db.txt.swap',mode='wt',encoding='utf-8') as wrife_f: for line in read_f: wrife_f.write(line.replace('SB','kevin')) os.remove('db.txt') os.rename('.db.txt.swap','db.txt')