1、 基础
1、文件操作3要素
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() | 获取光标位置,以字节为单位 |
2、读文件
1、相对/绝对路径打开读取
以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()
2、按照字符去读取
f=open(\'a.txt\',encoding=\'gbk\',mode=\'r\')#打开a.txt,指定编码和操作模式
f1=f.read(12)#读取文件
print(f1)
f.close()
3、按照行读取
一行一行读取
f=open(\'a.txt\',encoding=\'gbk\',mode=\'r\')#打开a.txt,指定编码和操作模式
f1=f.readline()#readline每次读取一行
print(f1)
f1=f.readline()
print(f1)
f.close()
4、多行读取
readlines,返回一个列表,列表的每一个元素是原文件的每一行
f=open(\'a.txt\',encoding=\'gbk\',mode=\'r\')#打开a.txt,指定编码和操作模式
f1=f.readlines()#readlines返回一个列表,列表的每一个元素是原文件的每一行
print(f1)
f.close()
5、for循环读取
f=open(\'a.txt\',encoding=\'gbk\',mode=\'r\')
for i in f:
print(i)#在循环之中可以设置读取方式
f.close()
6、rb操作非文本文件
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()
将视频文件移动到当前目录中进行实验
2、 写文件
文件写模式一共四种:w,wb,w+,wb+
1、文件不存在,创建文件,写文入内容
2、文件存在,清空原有内容在写入文件
3、操作非文本(二进制)文件
f=open(\'视频.mp4\',mode=\'rb\')
f1=f.read()#读取视频文件
f.close()
f2=open(\'视频2.mp4\',mode=\'wb\')
f2.write(f1)#写文件
f2.close()#写完晚间之后关闭
3、文件追加
文件的追加:a,ab,a+,ab+
追加文件
f=open(\'b.txt\',encoding=\'utf-8\',mode=\'a\')
f1=f.write(\'低头思故乡\')
f.close()
4、读写先后问题
这里涉及到光标的位置,光标的位置跟读取的位置息息相关
r+先读取在写入,文件不存在就报错,它是在文件的后面追加内容(读并追加),此时没有问题,但是如果先写入在读取就可能出问题了
如果先写在读,光标从前往后,你写了多少就会覆盖多少,但是可能出现乱码问题,以字节换字节
1、先读取在写入
f=open(\'b.txt\',encoding=\'utf-8\',mode=\'r+\')
f1=f.read()
#光标在哪里,就在那增加,因为你刚读取完毕所有,光标在最后面,所以就会在后面增加
print(f1)#举头望明月
f.write(\'疑是地上霜\')
f.close()
2、先写在读
这里涉及到光标的位置,光标的位置跟读取的位置息息相关,跟你把鼠标放在哪里没有关系
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+模式下先读取在写入么不是先写入在读取
5、光标获取
1、tell获取光标
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()
2、seek,寻找,调整光标
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()
3、flush刷新文件
修改完文件可能并没有马上保存,此时其它程序操作可能导致错误,此时刷新之后在关闭就没有问题了,刷新相当于保存了一下,类似于word的Ctrl+s保存
f=open(\'b.txt\',encoding=\'utf-8\',mode=\'a+\')
f.write(\'床前明月光\')
f.flush()
f.close()
2、with as 打开文件
with … as 变量名 ,是控制流语句,经常用来操作文件
with是一种上下文管理协议
as 变量,相当于起别名,方便操作
with as打开文件时常用方式
缺点:自动关闭文件句柄,是有一段时间的,这个时间不固定,所以这里就有可能产生问题,如果你在with语句中通过r模式打开a.txt文件,那么你在下面又以a模式打开a.txt文件,此时有可能你第二次打开a.txt文件时,第一次的文件句柄还没有关闭掉,可能就会出现错误,他的解决方式只能在你第二次打开此文件前,手动关闭上一个文件句柄
1、打开单个文件
with open(\'a.txt\',encoding=\'gbk\') as f1:
#as,将前面的内容用f1变量来进行指代,方便操作,变量符合命名规则的任意变量都可以
print(f1.read())
2、打开多个文件
with open(\'a.txt\',encoding=\'gbk\') as f1,open(\'b.txt\',encoding=\'utf-8\') as f2:
print(f1.read())
print(f2.read())
3、文件的修改
修改文件的流程
- 已读的模式打开源文件
- 以写的模式创建一个新文件
- 将源文件的内容读出来修改新内容。写入新文件
- 将源文件删除
- 将新文件重命名为源文件
任何软件修改文件都有上面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模式打开此文件时才会清空
来源:https://blog.csdn.net/qianshuiliyu/article/details/123186724
本站部分图文来源于网络,如有侵权请联系删除。