前言:
使用Python提供的open方法可以对文件进行读写操作
Python open() 方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数。
目录
open的介绍
open(file_path,mode,enconding) # 前两个参数必备
# 第一个参数 文件的路径地址,默认是相对路径查找,也可以使用绝对路径
# 第二个参数 文件的打开方式
# 第三个参数 打开文件的编码
# mode 三种模式:
# t(文本模式 默认)b(二进制模式)x(写模式,新建文件,如果已存在文件会报错)
mode 参数:
模式 | 描述 |
---|---|
t | 文本模式 (默认) |
x | 写模式,新建一个文件,如果该文件已存在则会报错 |
b | 二进制模式 |
x | 打开一个文件进行更新(可读可写) |
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等 |
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件 |
w+ | 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写 |
open的使用
+号给模式增加读写,目前测试只适用于r模式,但是不建议使用,因为每种模式都对某一方面占优势,一般情况下,读内容使用r即可,写内容使用w或者a即可
读文件内容
r 模式,用于读文件内容
# 将mode模式改为r,表示以读的形式打开这个文件
f = open('a.txt','r',encoding='utf-8') # 这里通过utf-8解码
'''
重点:在硬盘读取内容时,要进行解码,解码指定标准必须和文件存入硬盘时编码是一致的
否则会造成乱码。
可以尝试将写入文件时编码改成gbk,写入时放入一点中文,然后读取文件解码用utf-8,
这么做的结果就是 无法通过utf-8对gbk文件进行解码,最终报错
'''
body = f.read() # 读取文件内容
print(body)
f.close() # 关闭文件
读图片内容
rb 读二进制内容的文件如:图片、视频等
# 注意:这里不需要使用编码,因为我们本来就是拿二进制,进行编码会报错
f = open('white.jpg','rb') # 这里图片与我当前文件在同一文件夹内
print(f.read())
f.close()
写入文件内容
w 写模式,如果已存在文件那么会清空文件原有内容从头开始编辑,如果没有则创建
# 使用open对文件操作,默认就是以文本模式,这里w可以看成wt,t表示只能对文本操作
f = open('a.txt','w',enconding='utf-8')
'''
这里encoding代表,指定字符编码格式将文件内容写入硬盘
因为计算机只能识别二进制数,那么就需要对我们书写的字符进行编码
经过编码后,最终写入硬盘的都是二进制,
python3 默认就是utf-8编码格式
utf-8 作为最常用编码,但仍有部分文件内容是用于其他编码写入,所以经常达不到统一
所以有时在其他读文件时产生乱码现象
使用open以后,会返回一个文件对象
'''
f.write('123') # 对这个文件写入一点内容
f.close()
# 注意:使用完文件对象以后,通知操作系统关闭文件,避免占用系统资源。
执行完毕以后,会发现当前文件夹下多了一个a文件
再次使用w模式
f = open('a.txt','w',encoding='utf-8')
f.write('World')
f.close()
查看效果:原内容已经被清空,写入了新的内容
完整复制出一张图片
使用wb,表示往文件内写入二进制
f = open('white.jpg','rb')
source_img = f.read() # 先获取原图片的二进制内容
f2 = open('new_white.jpg','wb')
f2.write(source_img) # 原图片的二进制,写入新文件
f.close()
f2.close() # 记得关闭文件,避免占用系统资源
查看效果
优化操作
因为程序是先将文件内容读入内存,最后最写入一个新的文件,如果原文件容量较大,那么读入到内存里面会对内存造成很大的压力,所以建议使用下面这种方式:
f = open('white.jpg','rb') # 源文件
f2 = open('new_white.jpg','wb') # 创建一个新的图片文件
for i in f: # 每次读源文件一部分内容,写入新的文件,有效减少了对内存的压力
f2.write(i)
f.close()
f2.close() # 记得关闭文件,避免占用系统资源
# 相对大文件拷贝的一种优化方案,小文件可以使用上面那种
对文件进行追加内容
a 模式,将光标移到末行追加内容,如果文件不存在则创建文件
代码实现
f = open('a.txt','a',encoding='utf-8')
f.write('哈哈') # 往文件末尾追加内容
f.close()
'''
可以增加换行
f = open('a.txt','a',encoding='utf-8')
f.write('哈哈\n') # 表示输入完哈哈以后换行一次
f.close()
'''
实现后
ab 模式用于对文件追加二进制内容(不常用)
w模式与a模式不同的是在打开文件时的效果:
使用w模式:在打开文件时就会清空原有内容,再从头开始编辑。
使用a模式:只会用于追加内容。
如果是一个空文件,则两个模式效果相同
给予每种模式对文件的读写能力
使用+ 给模式提供未拥有的属性,如:
给r模式提供可以写的操作
给w模式提供可以读的操作
给a模式提供可以读的操作
给予r模式+号的话,可以拥有对文件的写能力
其中w模式是写入内容的,从头开始写内容,写完后光标默认是停留在最后一行的,如果给它+号赋予读的能力,那么也是读不了内容的,因为读内容是从光标当前位置开始向后读
a模式更不用说,默认光标就在最后一行,虽然说有读的能力,但是无法使用出来。
实例:
# 给r 模式增加写的能力
f = open('a.txt','r+',encoding='utf-8')
print(f.readable()) # 查看对文件是否有写能力 True 表示具备写的能力
f.write('1234') # 可以写入内容
# 给w 模式增加读的能力
f = open('a.txt','w+',encoding='utf-8')
print(f.readable()) # 查看对文件是否具备读能力
f.write('123') # 因为是w模式需要,需要写点内容
print(f.read()) # 发现读不出内容,因为是光标写入时走到末尾的原因
# 给a 模式增加读的能力
f = open('a.txt','a+',encoding='utf-8')
print(f.readable()) # 查看对文件是否具备读能力
f.write('123') # 写点内容
print(f.read()) # 发现读不出内容,默认光标直接跳到结尾
操作文件的常用方法
学习一下操作文件对象的几种常用方法,可以自如的操作文件
光标的移动
控制光标的移动,可以让光标停留任何位置
f = open('a.txt','r',encoding='utf-8')
print(f.read()) # 读取文件内容
print(f.read())
# 发现已经无法读取文件内容,是读文件是从头到尾读,读过一次 所以光标已经在最后一个了
'''
控制光标使用方法
f.seek(移动的字符个数,模式)
三种模式:
0:参照开头位置移动指针
1:参照当前光标位置移动指针
2:参照末尾位置移动指针
只有0模式可以在 t(文本模式)使用,1、2只能在b(二进制模式)下使用
print(f.tail()) # 查看光标当前的位置
'''
f = open('a.txt','r',encoding='utf-8')
print(f.read()) # 读取文件内容
f.seek(0,0) # 将光标移动到开头
print(f.read())
读取文件的常用方法
可以根据需求读取文件所需内容
t模式 read(找到的字符个数)
b模式 read(找到的字节个数) 1个中文3个字节 (基本不用这种形式读二进制文件)
f = open('a.txt','r',encoding='utf-8')
res = f.read(1) # 读取字符的个数,1代表光标只移动一下 读取第一个字符
# res = f.read(3) # 如果是rb模式,存在一个中文就要用3个字节来读
print(res)
按行读内容
f = open('a.txt','r',encoding='utf-8')
print(f.readline(),end='') # 第一次读取一行内容,光标停留在第一行末尾
123
print(f.readline(),end='') # 第二次读取二行内容,从第一行末尾读到第二行末尾
456
把文件内容按行读出来全部放入列表
f = open('a.txt','r',encoding='utf-8')
print(f.readlines(),end='') # 把所有内容都打印出来
写入文件的常用方法
可根据自身需要的方式写入文件
常规写法
f = open('a.txt','w',encoding='utf-8')
f.write('123\n456') # 全部写在一个引号内,不客观
f.close()
多个内容同时写入
f = open('a.txt','w',encoding='utf-8')
f.writelines(['123\n','456\n','789']) # 引入列表写入多个内容
f.close()
修改文件的流程结构
原理与计算机对文件的操作大致相同
改变文件内容的流程 第一种:
# 1、先将原文件读入内存
# 2、在内存对文件的内容进行修改
# 3、将内存写好的内容覆盖进去
with open('a.txt', 'r', encoding='utf-8') as f:
data = f.read()
print('查看文件改动前:')
print(data) # 查看改动之前
# 获取文件内容,将特定字符进行替换,这里将jack 替换成 tom
res = data.replace('jack', 'tom')
print('='*15)
with open('a.txt', 'w+', encoding='utf-8') as f:
print('文件改动后:')
f.write(res) # 将写好的内容覆盖进源文件
f.seek(0) # 移动指针到开头
print(f.read()) # 查看改动之后
# 这种方式对内存造成过分占用,因为需要一次性将源文件全部读入内存
执行代码后,由于计算机运行过快,导致我们看到的就是只是修改了部分内容,其实执行的是覆盖操作,可以看到 jack 已经变成 tom
代码执行效果
改变文件内容的流程 第二种:
import os
# 修改文件内容的流程 第二种:
# 1、创建一个用于交换文件
# 2、一行行读取源文件的内容到内存
# 3、将内存的文件内存进行操作,再一行行写入交换文件
# 4、删除源文件,将交换文件改成和源文件名称一样
# 节省内存空间,将文件内容分解读入新的文件,和上面复制图片的原理相同
with open('a.txt','r',encoding='utf-8') as f1,\
open('.a.txt.swp','w+',encoding='utf-8') as f2:
print('查看文件改动前:')
print(f1.read())
f1.seek(0) # 进行过read操作,将光标重新移动到行首
print('='*10) # 上下隔开
for line in f1.readlines(): # 读多行内容
f2.write(line.replace('jack','tom'))
f2.seek(0) # 进行过写操作,将光标移动到行首
print('查看文件改动后:')
print(f2.read())
os.remove('a.txt') # 删除源文件
os.rename('.a.txt.swp','a.txt') # 将交换文件名替换成 和原文件相同的名字
执行后效果,与上序效果相同,但底层原理不同:
演示字符乱码
# 对文件进行写入内容,使用编码为gbk
f = open('a.txt','w',encoding='gbk')
f.write('这是Python基础(3)文件处理') # 写入中文内容更容易看出效果
f.close()
# 读取文件内容,使用解码为utf-8
f2 = open('a.txt','r',encoding='utf-8')
print(f2.read())
f2.close()
因为这里编辑器设置的是utf-8解码,所以看到的是乱码的内容,并且运行的程序也报错了,因为通过utf-8 无法进行解码
如果后续打开一个文件出现乱码,不妨调整一下解码格式,这里调整成gbk成功读取到内容
UTF-8作为国际编码,而GBK是国家编码(太过局限),通用性不高,所以对文件进行处理建议使用UTF-8作为编码标准。如果遇到读取一个文件时产生乱码:两种情况
第一种:
在编码时,输入的字符使用的编码表无法识别,这样在存入硬盘后,直接就是存了一堆乱码,在读出来的内容也是乱码,那么这种情况无法解决,因为起步就错了。
第二种:
没有使用文件在存入硬盘时的编码进行解码,那么对这种情况只能进行尝试多个编码才配对。
with 上下文管理,这里使用with 用来管理open
# as 后面定义一个别名,通过这个别名来访问文件对象
with open('a.txt','r',encoding='utf-8') as f:
print(f.read())
# 使用完以后不用执行close操作,因为with会在我们使用完文件时会帮我们关闭文件
123
# 同时打开多个文件
# \表示转义符,意思是经过转义符后的内容还是属于同一行的,这样用于更加可观
# 如果不加转义符,那么会出现语法错误
with open('a.txt','r',encoding='utf-8') as f1,\ # 表示后面还有内容
open('b.txt','w',encoding='utf-8') as f2: # 记得冒号
print(f1.read()) # 读取文件a内容
print(f2.write('456')) # 新建文件b写入内容
123
# 不用担心占用系统资源,可同时管理多个文件
练习:循环创建文件并写入内容
words = 'abcdefghijklmnopqrstuvwxyz' # 定义26个字母
count = 1 # 进行一个计数
for i in words: # 遍历字符串就是把一个字符都拿过来
# 一个字母创建一个文件
with open(i + ".txt",'w',encoding='utf-8') as f:
# 第一个就是a1、第二个就是b2
f.write(i + str(count)) # count转换成字符串类型才能与字符进行连接
count += 1 # 每次数字加一
练习:循环删除文件,这里提前用到一个库的知识
import os
words = 'abcdefghijklmnopqrstuvwxyz'
for i in words: # 循环26的字母
os.remove(i + '.txt') # 通过这个库提供的remove方法删除文件
练习:不断往文件写入内容
import time
with open('success.txt','a',encoding='utf-8') as f:
while True:
print('正在写入内容:GoodMorning')
f.write('GoodMorning\n')
time.sleep(0.5) # 写入一次以后,使用这个模块暂停0.5秒钟
'''
因为当前进程运行过程中往硬盘写入时,并没有立马写入进去,会被缓存起来,等待缓存很多以后再一次性写进去。
所以我们执行flush不对其进行缓存,立马写入进去。
'''
f.flush()
练习:实时监测文件添加的内容
import time
with open('success.txt','r') as f:
f.seek(0,2)
print('正在检测文件:success')
while True:
line = f.readline() # 每次读取文件一行内容
# 如果没有内容就暂停0.1秒钟,注意:这0.1对计算机来是一个缓解压力的时间
# 不然死循环,会很大消耗计算机资源
if len(line) == 0:
time.sleep(0.1)
else: # 如果有内容就打印出来,不换行,因为写入时已经有换行
print('success文件新增了一行内容:',line,end='')
下一篇博客 函数:https://blog.csdn.net/m0_46958731/article/details/110121539
技术小白记录学习过程,有错误或不解的地方请指出,如果这篇文章对你有所帮助请
点赞收藏+关注
谢谢支持!