文件操作
文件操作的基本流程
# 拿到文件句柄,打开文件 f = open("test2.txt", "r", encoding="utf8") # 操作文件 data = f.read() print(data) # 关闭文件 f.close()
说明:这文件操作首先拿到了文件句柄,然后进行操作,操作完成再关闭文
# 拿到文件句柄,打开文件 f = open("test2.txt", "w", encoding="utf8") # 操作文件 f.write("春风又绿江南岸 明月何时照我还 我本将心想明月 怎奈明月照沟渠") # 关闭文件 f.close()
说明:这里的写操作,开始打开文件,然后进行写操作,写操作将内容写到了内存中的缓存区中,这是因为硬盘的读写速度相对于cpu和内存的速度太慢,为了增加效率才设有这么个缓存区的。当f.close()操作之后,解释器开始将内容从缓存区中写入磁盘中
# 拿到文件句柄,打开文件 f = open("test2.txt", "w", encoding="utf8") # 操作文件 f.write("春风又绿江南岸 明月何时照我还 我本将心想明月 怎奈明月照沟渠 ") # 刷新缓存区 f.flush() f.write("煮豆燃豆萁 豆在釜中泣 本是同根生 相煎何太急") # 关闭文件 f.close()
说明:这种flush操作,每一步写操作,就flush一次,就是在写一句到缓存区,然后就写入磁盘中,因为这个flush操作的功能,我们可以使用flush制作一个进度条
# 方法1: import time import sys for i in range(30): sys.stdout.write("*") # 类似文件操作的写操作 sys.stdout.flush() time.sleep(0.1) # 方法2: import time for i in range(30): print("*", end="", flush=True) # 利用print函数的flush参数 time.sleep(0.1)
文件操作的几种模式
文件操作的几种模式分别有:r, r+, rb, w, w+, wb, a, a+
r
模式
# r模式 --->r模式启动,指针从文件的最前面开始 with open("test.txt", "r", encoding="utf8") as f: data = f.read() print("data的数据内容是:", data) data2 = f.read() print("data2的数据内容是:", data2) data的数据内容是: 将军百战穿金甲,不破楼兰终不还 离离原上草,一岁一枯荣 野火烧不尽,春风吹又生 谁知盘中餐,粒粒皆辛苦 --<悯农>世上无难事,只要肯攀登 ---《悯农》将军百战穿金甲,不破楼兰终不还离离原上草,一岁一枯荣野火烧不尽,春风吹又生谁知盘中餐,粒粒皆辛苦 --<悯农>世上无难事,只要肯攀登---《悯农》 data2的数据内容是:
我们可以发现data
是从文件最开头开始读取的,而第二步read
操作读取到的内容是空的,是因为第一步read
操作,导致指针已经到了文件的最后面了,所以是从最后面开始的,最后面没有了内容,所以是空的
w
模式
# w模式--->w模式启动,如果文件不存在,创建文件再写入,如果文件存在,将文件的内容格式化清除,然后再写入 with open("test.txt", "w", encoding="utf8") as f: f.write("离离原上草 一岁一枯荣 野火烧不尽 春风吹又生 谁知盘中餐 粒粒皆辛苦") with open("test.txt", "r", encoding="utf8") as f: print(f.read()) f.seek(9) print(f.read())
说明:seek方法是将指针移到指定的位置,里面的参数要是3的倍数,因为一个中文字符是由3个byte组成
r+
模式
r模式和r+模式类似,指针也是从最开始,r+模式除了可以读,还可以写 with open("test2.txt", "r+", encoding="utf8") as f: f.write("离离原上草 一岁一枯荣 野火烧不尽 春风吹又生 谁知盘中餐 粒粒皆辛苦") # 指针到了最后面 f.seek(0) # 将指针移到最前面 print(f.read()) f.seek(9) print(f.read()) 运行结果: 离离原上草 一岁一枯荣 野火烧不尽 春风吹又生 谁知盘中餐 粒粒皆辛苦 上草 一岁一枯荣 野火烧不尽 春风吹又生 谁知盘中餐 粒粒皆辛苦
w+
模式
w+模式和w模式一样,都是先格式化清除再写入
代码省略
a
模式
a模式,如果文件不存在,就创建文件,如果文件存在且有内容,此时指针在文件的最后面,就从文件的末尾追加,这种模式只能写
代码省略
a+
模式
a模式是可以读写的,写的话是写到最后面
wb
模式和rb
模式
wb
模式和 rb
模式都是针对二进制数据操作的,如图片
文件操作的几种方法
文件操作的方法有写write
和writelines
,文件操作方法读有read
和readline
还有readlines
read
方法
read
方法既可以带参数也可以不带参数,当不带参数的时候,默认将文件的 所有内容全部读取,如果带了参数,比如read(5)
,是指读取指针
后面的5个字符
with open("test2.txt", "r", encoding="utf8") as f: print(f.read(5)) # 在爬虫中,我们通常传入的参数是1024 print(f.read(5)) # 读取结果 离离原上草 一岁一枯
如果文件的内容很多,我们通常通过循环的方法来读取
with open("test2.txt", "r", encoding="utf8") as f: data = f.read(5) while data: print(data) data = f.read(5)
readline
方法
readline
方法是一行一行读取,如果需要读取全部内容,就需要循环读取
with open("test2.txt", "r", encoding="utf8") as f: data = f.readline() while data: print(data.strip()) data = f.readline() 运行结果: 离离原上草 一岁一枯荣 野火烧不尽 春风吹又生 谁知盘中餐 粒粒皆辛苦
readlines
方法
readlines
方法读取的内容是列表格式
with open("test2.txt", "r", encoding="utf8") as f: print(f.readlines()) 运行结果: ['离离原上草 ', '一岁一枯荣 ', '野火烧不尽 ', '春风吹又生 ', '谁知盘中餐 ', '粒粒皆辛苦'] with open("test2.txt", "r", encoding="utf8") as f: datas = f.readlines() for data in datas: print(data.strip())
这样我们就可以通过遍历for循环取到相对应的值,或者我们想要对某行进行操作
我们想要对谁知盘中餐
这一行写入悯农
# 方法1: with open("test2.txt", "r", encoding="utf8") as f: datas = f.readlines() num = 1 for data in datas: if num == 5: data = f"{data.strip()}--->{'《悯农》'}" print(data) else: print(data.strip()) num += 1 运行结果: 离离原上草 一岁一枯荣 野火烧不尽 春风吹又生 谁知盘中餐--->《悯农》 粒粒皆辛苦 # 我们会发现上面的代码还有改进优化的地方,因为`print`函数使用了两次有些多余 with open("test2.txt", "r", encoding="utf8") as f: datas = f.readlines() num = 1 for data in datas: if num == 5: data = f"{data.strip()}--->{'《悯农》'}" print(data.strip()) num += 1 # 继续优化 with open("test2.txt", "r", encoding="utf8") as f: datas = f.readlines() for num, data in enumerate(datas, 1): if num == 5: data = f"{data.strip()}--->{'《悯农》'}" print(data.strip()) num += 1 # 方法2:通过列表取值的方式来改 with open("test2.txt", "r", encoding="utf8") as f: datas = f.readlines() data = f"{datas[4].strip()}---->{'《悯农》'}" print(data) 运行结果: 谁知盘中餐---->《悯农》 # 方法3: with open("test2.txt", "r", encoding="utf8") as f: num = 1 for data in f: if num == 5: data = f"{data.strip()}--->{'《悯农》'}" print(data.strip()) num += 1 这里直接拿到f文件,将文件做成了一个迭代器,更提倡这种方法
注意:这里的修改并没有对原文件进行修改,而只是改了内存打印的数据
如果我们想要去改变原文件的内容呢?
我们实验发现没法去改变,但我们可以通过得到这个源文件的数据,然后修改,再写到另一个文件中
with open("test2.txt", "r", encoding="utf8") as f: num = 1 for data in f: if num == 5: data = f"{data.strip()}--->{'《悯农》'}" print(data.strip()) # 循环读取 f2 = open("test1.txt", "a+", encoding="utf8") f2.write(data) # 循环写入 f2.flush() f2.close() num += 1
我们可以查看test1.txt文件中的内容
writelines
方法
writelines
和readlines
两种方法是对应的,它写入的是列表数据,而readlines
方法相应地读取列表数据
with open("test3.txt", "a", encoding="utf8")as f: f.writelines(["将军百战穿金甲 ", "不破楼兰终不还"])
seek
方法和tell
方法
seek
方法可以随意将指针调到任意处
tell