python操作文件至少满足3个条件
操作系统默认编码 | 编码 |
---|---|
windows | gbk |
Linux | utf-8 |
mac | utf-8 |
文件操作模式 | 说明 |
---|---|
r | 以只读的形式打开文件,默认就是r模式 |
w | 以只写的形式打开这个文件,如果这个文件存在就覆盖这个文件内容来写(先删除原内容在写),不存在就创建文件 |
a | 在文件后面追加内容,文件不存在创建文件 |
rb | 以只读的形式打开一个二进制文件 |
wb | 以只写的形式打开一个二进制文件,如果这个文件存在就覆盖这个文件来写东西(先删除原内容在写),否则创建文件 |
ab | 在一个二进制文件后面追加内容 ,文件不存在创建文件 |
r+ | 以读写的形式打开一个文件,如果这个文件不存在会报错 |
w+ | 以读写的形式打开一个文件,如果这个文件存在就覆盖这个文件内容来写(先删除原内容),不存在就创建文件 |
a+ | 以读写的形式打开文件可以在文件后面追加内容,文件不存在就创建 |
rb+ | 以读写的形式打开一个二进制文件,不存在就报错 |
wb+ | 以读写的形式打开一个二进制文件,如果这个文件存在就覆盖这个文件内容来写(先删除原内容在写),不存在就创建文件 |
ab+ | 以读写的形式打开二进制文件可以在文件后面追加内容 |
原理:读取文件是将文件一次性全部加载到内存当中,如果文件过大,内存容不下,导致文件读取失败,此时可以使用for循环读取文件
对文件的操作又叫做对文件句柄的操作
对文件的操作有:读、写、追加
对文件的操作 | 模式 | 模式写法 |
---|---|---|
读 | 4种模式 | r,rb,r+,r+b |
写 | 4种模式 | w,wb,w+,wb+ |
追加 | 4种模式 | a,ab,a+,ab+ |
操作方法:
功能 | 说明 |
---|---|
read() | 读取指定字符数量,默认全部 |
readline() | 按照行读取 |
readlines() | 以列表的形式放回,一行一个字符串 |
tell() | 获取光标位置,以字节为单位 |
以a.txt中的床前明月光测试
1、相对路径读取
f=open('a.txt',encoding='gbk',mode='r')#打开a.txt,指定编码和操作模式 f1=f.read()#读取文件 print(f1) f.close()#读取完之后关闭文件
2、绝对路径读取
f=open(r'E:\python_project\a.txt',encoding='gbk',mode='r')#打开a.txt,指定编码和操作模式 f1=f.read() print(f1) f.close()
f=open('a.txt',encoding='gbk',mode='r')#打开a.txt,指定编码和操作模式 f1=f.read(12)#读取文件 print(f1) f.close()
一行一行读取
f=open('a.txt',encoding='gbk',mode='r')#打开a.txt,指定编码和操作模式 f1=f.readline()#readline每次读取一行 print(f1) f1=f.readline() print(f1) f.close()
readlines,返回一个列表,列表的每一个元素是原文件的每一行
f=open('a.txt',encoding='gbk',mode='r')#打开a.txt,指定编码和操作模式 f1=f.readlines()#readlines返回一个列表,列表的每一个元素是原文件的每一行 print(f1) f.close()
f=open('a.txt',encoding='gbk',mode='r') for i in f: print(i)#在循环之中可以设置读取方式 f.close()
rb是以二进制的形式读取文件,可以操作电脑上的任意文件,因为文件在电脑上就是以二进制的形式保存的,所以在操作的时候也不需要指定编码
rb模式用于操作非文本文件,视频、音乐等,当然也能操作文本文件,操作非文本文件不用指定编码
rb模式操作的是二进制,所以不用制定编码,可以操作视频,音乐、图片等所有文件,因为所有文件在计算机的底层都是以二进制的形式保存的
1、操作文本
f=open('a.txt',mode='rb')#rb模式操作的是二进制,所以不用制定编码,可以操作视频,音乐、图片等所有文件,因为所有文件在计算机的底层都是以二进制的形式保存的 f1=f.read() print(f1) f.close()
2、操作非文本
f=open('视频.mp4',mode='rb')#rb模式操作的是二进制,所以不用制定编码,可以操作视频等所有文件 f1=f.read() print(f1) f.close()
将视频文件移动到当前目录中进行实验
文件写模式一共四种:w,wb,w+,wb+
3、操作非文本(二进制)文件
f=open('视频.mp4',mode='rb') f1=f.read()#读取视频文件 f.close() f2=open('视频2.mp4',mode='wb') f2.write(f1)#写文件 f2.close()#写完晚间之后关闭
文件的追加:a,ab,a+,ab+
f=open('b.txt',encoding='utf-8',mode='a') f1=f.write('低头思故乡') f.close()
这里涉及到光标的位置,光标的位置跟读取的位置息息相关
r+先读取在写入,文件不存在就报错,它是在文件的后面追加内容(读并追加),此时没有问题,但是如果先写入在读取就可能出问题了
如果先写在读,光标从前往后,你写了多少就会覆盖多少,但是可能出现乱码问题,以字节换字节
f=open('b.txt',encoding='utf-8',mode='r+') f1=f.read() #光标在哪里,就在那增加,因为你刚读取完毕所有,光标在最后面,所以就会在后面增加 print(f1)#举头望明月 f.write('疑是地上霜') f.close()
这里涉及到光标的位置,光标的位置跟读取的位置息息相关,跟你把鼠标放在哪里没有关系
f=open('b.txt',encoding='utf-8',mode='r+') f.write('12你好世界') f1=f.read() print(f1) f.close()
如果先写在读,光标从前往后,你写了多少就会覆盖多少,但是可能出现乱码问题,以字节换字节
就是之前是汉字,一个文字在utf-8是3字节,你换数字,一个数字1字节,1字节对应3字节,无法对应,就出错,甚至于其他符号;因为你写的时候是一个字符替换一个字符而不是替换一个编码
解决:以字符替换字符就好了
恢复之前的测试
f=open('b.txt',encoding='utf-8',mode='r+') f.write('你好') f1=f.read() print(f1) f.close()
所以我们在r+模式下先读取在写入么不是先写入在读取
tell():获取光标的位置,以字节为单位
光标的位置跟读取的位置息息相关,跟你把鼠标放在哪里没有关系
f=open('b.txt',encoding='utf-8',) print(f.tell())#tell根据字节获取光标,此时没有读取,光标的位置在0的位置, f1=f.read(2)#读取两个字符中文之后,光标的位置就成了6,在utf-8中,一个中文3字节 print(f.tell())#此时光标的位置是6 f.close()
seek(偏移量,起始位置)
起始位置参数 | 说明 |
---|---|
0 | 光标在开头 |
1 | 光标在当前位置 |
2 | 光标在最后一个位置 |
寻找,调整光标的位置,按照字节调整(偏移量),这个字节必须是某个字符的开始,不能是中间,否则报错
1、偏移量
f=open('b.txt',encoding='utf-8') f.seek(0)#从第几个字节的光标开始往后,0就是从头开始,就是偏移量 print(f.read())#举头望明月 f.seek(3)#偏移3字节 print(f.read())#头望明月 f.close()
2、当前光标位置
f=open('b.txt',encoding='utf-8') # print(f.seek(6)) # print(f.read()) print(f.read(2))#读取两个字符 print(f.seek(0,1))#当前光标的位置,6 print(f.read())#读取全部剩下的内容,你在读取就从刚在的光标开始去取了, print(f.seek(0,1))#当前光标与光标最后的位置一样,15 print(f.seek(0,2))#光标最后的位置,15 f.close()
修改完文件可能并没有马上保存,此时其它程序操作可能导致错误,此时刷新之后在关闭就没有问题了,刷新相当于保存了一下,类似于word的Ctrl+s保存
f=open('b.txt',encoding='utf-8',mode='a+') f.write('床前明月光') f.flush() f.close()
with … as 变量名 ,是控制流语句,经常用来操作文件
with是一种上下文管理协议
as 变量,相当于起别名,方便操作
with as打开文件时常用方式
缺点:自动关闭文件句柄,是有一段时间的,这个时间不固定,所以这里就有可能产生问题,如果你在with语句中通过r模式打开a.txt文件,那么你在下面又以a模式打开a.txt文件,此时有可能你第二次打开a.txt文件时,第一次的文件句柄还没有关闭掉,可能就会出现错误,他的解决方式只能在你第二次打开此文件前,手动关闭上一个文件句柄
with open('a.txt',encoding='gbk') as f1: #as,将前面的内容用f1变量来进行指代,方便操作,变量符合命名规则的任意变量都可以 print(f1.read())
with open('a.txt',encoding='gbk') as f1,open('b.txt',encoding='utf-8') as f2: print(f1.read()) print(f2.read())
修改文件的流程
任何软件修改文件都有上面5个流程,只不过是系统自动去帮我们完成而已
1、修改单个内容
import os with open('b.txt',encoding='utf-8',) as f1,open('b.txt.bak',encoding='utf-8',mode='w') as f2: 旧文件=f1.read() 新文件=旧文件.replace('望明月','照大地')#修改的内容 f2.write(新文件) os.remove('b.txt')#删除原文件 os.rename('b.txt.bak','b.txt')#将修改的新文件重新命名成原文件
2、修改多个内容
将所有照大地修改为望明月
import os with open('b.txt',encoding='utf-8',) as f1,open('b.txt.bak',encoding='utf-8',mode='w') as f2: 旧文件=f1.read() 新文件=旧文件.replace('照大地','望明月')#修改的内容,不指定次数,默认改全部 f2.write(新文件) os.remove('b.txt')#删除原文件 os.rename('b.txt.bak','b.txt')#将修改的新文件重新命名成原文件
或者
import os with open('b.txt',encoding='utf-8',) as f1,open('b.txt.bak',encoding='utf-8',mode='w') as f2: for i in f1: 旧文件=f1.read() 新文件=旧文件.replace('照大地','望明月')#修改的内容 f2.write(新文件) os.remove('b.txt')#删除原文件 os.rename('b.txt.bak','b.txt')#将修改的新文件重新命名成原文件
w模式对文件句柄没有关闭,就可以一直写入,关闭文件句柄,再次以w模式打开此文件时才会清空