概念:文件是数据存放的容器,它可以持久性的存储数据内容
1.文件的主要操作流程
1.1 文件打开
- 函数 open(file,mode,encoding = “处理编码方式”)
- file:文件路径(python在当前执行文件所在目录中查找指定文件)
注:python中的文件路径为相对路径,输入相对于当前所在文件夹的路径即可,相对路径行不通时,可使用绝对路径
- mode:操作模式
模式 | 含义 | 文件指针位置 |
---|---|---|
r(默认) | 以只读方式打开文件 | 1.文件的指针将会放在文件的开头 2.文件不存在, 会报错 |
w | 以只写方式打开文件 | 1.文件的指针将会放在文件的开头 2.文件不存在, 会自动创建一个新文件 |
a | 以追加方式(只写)打开文件 | 1.文件的指针将会放在文件结尾 2.文件不存在, 会自动创建一个新文件 |
增加b (rb wb ab) | 以二进制格式进行操作文件读写 | 二进制文件(图片、视频、音频.......) |
增加+ (r+ w+ a+ rb+ rw+ ra+) | 以 "读写模式" 进行打开 | 1.其他特性基本和 + 前面的模式一致 2.但是关于部分操作, 有细节区别 |
- 表格最后的细节区别举例(r+和r)
- 对于r+,若直接写入,则会覆盖开头的内容;若先读取内容在写入,则会在最后追加内容。 这是因为读取内容后,文件指针位置由开头移到了最后
1.2 文件读写
文件读写时,一般以 f.函数名()的格式去操作,其中 f 为管道,即 f = open(file,mode)
1.2.1 定位
- f.tell() 查看file文件当前指针位置
- f.seek( self ,[0,1,2]) 相对于某个指定位置,增加指针的偏移量
self : 偏移量
[0,1,2]:相对于哪个位置的偏移量(0开头“默认”,1当前位置,2末尾)
- 注意:文本文件的操作模式下(不带b),只能写0
如果想要写1或者2, 必须在二进制文件操作模式下(带b)
f = open("jj.txt","r+") # 文件内容为123456789 相对路径,只需输入“jj.txt”即可
print(f.tell()) # 开始指针位置是0
f.seek(2,0) # 将指针向右偏移两个位置
print(f.tell()) # 偏移后指针位置为2
print(f.read()) # 从位置2开始读取文件
print(f.tell()) # 读取文件后,指针位置移至最后,为9
1.2.2 读取
- 读取文件后,下标会自动后移
函数 | 作用 | 备注 | 适用 |
---|---|---|---|
f.read(字节数) | 从指针位置开始读取指定字节数的数据 | 字节数:读取的文件内容长度(从指针位置开始算),默认为总长度 | 一次性读取 适合小文件 |
f.readline( [limit] ) | 读取一行的数据 | 换行会多占两个字节数 limit:限制的最大字节数 | 按行读取 适合大文件 |
f.readlines() | 自动地将文件按换行符进行处理,将处理好的每一行组成一个列表返回 | 123 456 789 输出如下: | 一次性读取 适合小文件 |
f.readable() | 判定文件是否可读 | | 在操作文件前,可以利用该函数进行容错处理 |
1.2.3 写入
- f.write("内容") 从指针位置开始写入文件内容(写入方式(追加/覆盖)由mode决定)
- 返回值是写入的字节长度
- f.writeable() 判定文件是否可写 一一> 容错处理
1.3 文件关闭
- 为什么要关闭文件?
(1)可以释放系统资源 (2)立即清空缓冲区的内容到磁盘文件中
文件在写入时会先写入缓冲区,再在某个时机一次性传输给磁盘文件,所以如果不关闭
文件可能会造成缓冲区数据丢失,没有传送到磁盘文件中
- f.close() 关闭文件
- f.flush() 清空缓冲区内容到磁盘文件中
2.文件的其他相关操作
该节中操作均是基于os模块,所以需要先导入os模块:import os
在windows系统中,书写文件路径时,各级之间应该用反斜杠(/)而不是斜杠(\)
函数 | 操作 | 备注 |
---|---|---|
os.rename(“old name”,“new name”) | 修改单级 目录/文件 名称 | 若要修改多级 用os.renames() |
os.remove(“文件名”) | 删除文件 | |
os.rmdir("目录名") | 删除 单级 目录 | 如果文件夹非空,会报错,防止错删 |
os.removedirs("目录名") | 递归的 删除多级目录 | |
os.mkdir("文件夹名称") | 创建 目录(文件夹) | 不支持多级目录创建 |
os.getcwd() 无参数 | 获取当前目录 | |
os.chdir("目标目录") | 改变默认(当前)目录 | |
os.listdir("文件夹") | 获取目录内容列表 | 输入“./”代表当前目录 输入“../”代表上一级目录 |
- 单级目录 / 多级目录
3.案例
3.1 案例一:文件复制
- 要求:将一个文件的内容复制到另一个副本中
# 案例:复制文件内容至新的文件中
# 步骤分析:获取内容 ————> 写入另一个文件 ————> 关闭文件
# step1 以只读模式打开复制的文件,以追加模式打开副本文件
source_f = open("jj.txt","r")
write_f = open("gg.txt","a")
# step2 从源文件中读取内容,写入到目标文件中
content = source_f.read()
content = str(content) # 转化为字符类型
write_f.write(content)
# step3 关闭文件
source_f.close()
write_f.close()
这时,如果出现以下报错:
是因为,我们的源文件是利用UTF-8编码处理的,但系统默认使用GBK编码处理,导致方法不统一
此时我们只需要修改step1中的语句如下,统一两个文件的编码即可
source_f = open("jj.txt","r",encoding="UTF-8")
write_f = open("gg.txt","a",encoding="UTF-8")
- 注意:如果文件较大,我们尽量要避开使用f.read(),这样会占用较大内存,此时step2可以改用如下的循环结构,分多次读取内容
# step2 从源文件中读取内容,写入到目标文件中
while True:
content = source_f.read(50) #每次只读取50个字节,读完后指针后移
content = str(content)
if len(content) == 0: #若读取字节数为0,则停止
break
write_f.write(content)
3.2 案例二:文件分类
-
要求: 给定一批文件,有很多类型(jpg,txt...),按照文件的后缀名,划分到不同的文件夹,并生成txt格式的文件清单
# 案例二:文件分类
# 思路梳理: 遍历文件 ————> 获取文件后缀名 ————> 放入对应文件夹
# step1 获取所有文件名称
import os
import shutil
file_list = os.listdir("文件操作")
if not os.path.exists("file"):
os.mkdir("file") #如果没有file文件夹,就新建一个用于存放
# step2 遍历所有文件,获取文件后缀名
# 具体方法:先获取最后一个.的位置,然后根据这个位置,获取后面所有内容即为文件后缀名
for name in file_list:
start = name.rfind(".") #获取最后一个.的位置
houzhui = name[start+1:len(name)] #切片
houzhui = str(houzhui)
# step3 查看是否有相应目录,如果有,放入;如果没有,创建
mulu = os.listdir("file")
if houzhui not in mulu:
os.mkdir(f"file/{houzhui}")
shutil.move(f"文件操作/{name}",f"file/{houzhui}")
# step4 利用递归函数,列出文件夹及子文件的列表清单,再生成txt格式的文件清单
def listfiles(dir,file): #利用递归函数
#列举出当前给定的文件夹下的所有子文件夹 以及子文件,再进行遍历
file_list2 = os.listdir(dir)
for files in file_list2:
print_name = dir + "/" + files # 完整路径
if os.path.isdir(print_name): #一定要把路径写完整
file.write("\n" + print_name + "\n")
listfiles(print_name,file) #一直递归查找子文件
else:
file.write("\t" + files + "\n")
f = open("list.txt","a",encoding="UTF-8")
listfiles("file",f)
最终效果如下: