文件处理模式---b模式
1.与 t 模式类似,只能与a,r,w连用
2.能打开图片文件.文本文件...不同于t模式的局限性,获得的为bytes类型,不能指定字符编码
3.打开文本文件与图片文件所获得的bytes不同
with open('1.jpg','rb') as f: data=f.read() print(data) print(data.decode('utf-8')) #--->UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte #图片的Bytes不能字符编码 with open('a.txt','rb') as f: data=f.read() print(data) print(data.decode('utf-8')) #--->b'\xe5\x95\x8a\xe5\x95\x8a\xe5\x95\x8a\xe5\x95\x8a\xe5\x95\x8a\xe5\x95\x8a' #直接将数据从硬盘加载到内存中(不经过字符编码,直接得到utf-8编码格式的二进制) #---> 啊啊啊啊啊啊 #将utf-8格式的二进制解码成unicde形式
a+,r+,w+:可读可写
文件内容:
你瞅啥 你愁啥 哈哈哈
with open('a.txt','r+t',encoding='utf-8') as f: line=f.readline() print(line) f.write('\n我在哪?')
执行上面代码,
以r模式打开文件时,光标跑到文件开头,readline()读取一行,f.write()基于光标此时位置写入
but ---->执行结果:
你瞅啥 你愁啥 哈哈哈 我在哪?
哈?在写入数据的时候光标跑到了最后---->原因:这与数据在硬盘上的存储原理有关
从文件直观的角度看,我们插入数据是将插入内容后的所有数据统统后移,然而,硬盘是基于磁工作的,一圈圈写入数据,这咋移?
文件内容:
你好hello
执行代码--->
with open('a.txt','r+t',encoding='utf-8') as f: f.seek(3) f.write('哈哈') 执行结果--->你哈哈lo 对 '好hel' 造成了覆盖 注: with open('a.txt','r+t',encoding='utf-8') as f: f.seek(3) f.write('s') 执行结果--->你s��hello s只覆盖了好这个字符的一个字节
注:如果在文件打开的时候不指定encoding可能会报错,原因是:
1.f =opne('') --->给操作系统发送请求,并接受文件操作接口
2.在未指定字符编码的情况下,win操作系统使用默认的字符编码(gbk)解码硬盘中的utf-8格式(之前以utf-8格式写入的),
这又是数据读取字符编码不一致导致。
文件的修改:
基础知识:硬盘上的数据是不能被修改的(基于磁写数据),只能是新数据覆盖原数据达到删除效果
1.例如对于文件系统:拥有super block(相对于一家之长),innode block(储存文件源数据:权限....指针),direcotry block(目录块,用于储存文件的映射关系:a.txt ----->a.txt的innode号) ,block块(用于储存数据)
2.查找一个E:\a.txt文件,从过程来看:系统先找到E:\的innode号,根据源数据内的指针------>找到direcotry block,得到a.txt的innode号,再根据innode号找到block块:获取数据
3.删除一个a.txt文件,从过程来看:1.先在super block上标记a.txt的innode号为free状态,2.切断direcotry block块中的对应关系.3.在block储存块中标记储存a.txt的block为free空闲状态(数据仍存在) 等到下次有文件b.txt要写入硬盘时,super block块随机将原a.txt的innode号分配给b.txt造成覆盖(也有可能没有分配出去,因此重新建立关系,就可能恢复数据)
修改文件的两种方法:
1.-------->a.先将文件内容全部读到内存中
b.在内存中完成修改
c..将修改后的内容覆盖到原文件 (不适用修改过大的文件)
优点:在文件修改过程中不会占用两份硬盘资源
缺点:在修改文件的时候,一次性的将文件读入,过大的文件会使内存...
原文件内容 1111 2222 3333 with open('test.txt','r',encoding='utf-8') as f: data=f.read() data=data.replace('3333','1111') with open('test.txt','w',encoding='utf-8') as f: f.write(data) 修改后的文件 1111 2222 1111
2.--------->a..以只读的方式打开原文件,以写的方式打开新文件
b.按行的方式读文件
c.判断,如果为需要修改的文件内容,则替换,否则,保持原文件内容,按行写入
d.删除原文件,将新文件命名为原文件.
优点:同一时刻在内存中只存在原文件的一行数据,不会过多的占用内存资源
缺点:在修改文件的时候,在硬盘中会存在两份相同数据文件(原文件和目标文件)
原文件内容 bob 123456789 00 tom 123456789 11 jam 123456789 22 import os with open('test.txt','r',encoding='utf-8') as f, \ open('test2.txt', 'a', encoding='utf-8') as f1: for line in f: if 'tom'in line: line=line.replace('tom','tomx') f1.write(line) os.remove('test.txt') os.rename('test2.txt','test.txt') 新文件内容 bob 123456789 00 tomx 123456789 11 jam 123456789 22