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')
f1=f.read()
print(f1)
f.close()
 2、绝对路径读取
f=open(r'E:\python_project\a.txt',encoding='gbk',mode='r')
f1=f.read()
print(f1)
f.close()
2、按照字符去读取
f=open('a.txt',encoding='gbk',mode='r')
f1=f.read(12)
print(f1)
f.close()

3、按照行读取
一行一行读取
f=open('a.txt',encoding='gbk',mode='r')
f1=f.readline()
print(f1)
f1=f.readline()
print(f1)
f.close()

4、多行读取
readlines,返回一个列表,列表的每一个元素是原文件的每一行
f=open('a.txt',encoding='gbk',mode='r')
f1=f.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')
f1=f.read()
print(f1)
f.close()
 2、操作非文本
f=open('视频.mp4',mode='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())
f1=f.read(2)
print(f.tell())
f.close()
2、seek,寻找,调整光标
seek(偏移量,起始位置)
起始位置参数 | 说明 |
---|
0 | 光标在开头 | 1 | 光标在当前位置 | 2 | 光标在最后一个位置 |
寻找,调整光标的位置,按照字节调整(偏移量),这个字节必须是某个字符的开始,不能是中间,否则报错
 1、偏移量
f=open('b.txt',encoding='utf-8')
f.seek(0)
print(f.read())
f.seek(3)
print(f.read())
f.close()
2、当前光标位置
f=open('b.txt',encoding='utf-8')
print(f.read(2))
print(f.seek(0,1))
print(f.read())
print(f.seek(0,1))
print(f.seek(0,2))
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:
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模式打开此文件时才会清空

|