文件操作
目标
文件操作的作用
文件的基本操作
打开
读写
关闭
文件备份
文件和文件夹操作
文件操作的作用:
读取内容,写入内容,备份内容等
文件操作就是把一些数据存放起来,可以让程序下一次执行的时候直接使用,而不必重新
制作一份,省时省力
文件操作的步骤
1.打开文件 2.读写等操作 3.关闭文件 如果文件不关闭,这个文件将一直占用计算机内存 可以只打开或关闭文件,不进行任何操作
open 是Python调用的操作系统(windows,linux,等)的功能,而windows的默认编码方式为gbk,
linux默认编码方式为utf-8,所以你的文件用什么编码保存的,就用什么方法打开,一般都是用utf-8。
mode为打开方式:常见的有r,w,a,r+,w+,a+.rb,wb,ab,等16种,默认不写,是r。
流程就是打开文件,产生一个文件句柄,对文件句柄进行相应操作,关闭文件。
open函数必须搭配.close()方法使用,先用open打开文件,然后进行读写操作,最后用.close()释放文件。open函数有八个参数
file:文件路径或文件描述符。如为文件路径则是str类型,如是文件描述符,则是一个非负整数。文件描述符使用较少,通常情况下都传入文件路径。
mode:操作模式,可选,str类型,默认为r。可选值包括r、r+、w、w+、a、a+、x、x+、rb、wb、ab、xb、rt、at、wt、xt这16种。乍一看比较乱,其实很好理解。基本操作模式有四种,r、w、a、x,分别代表读、写、追加、创建新文件(xor 异或模式)。
Python open和with open用法和区别
使用open打开文件,必须要使用close关闭文件,所以,为了保证无论是否出错都能正确地关闭文件。
with open 自动关闭文件,可以不用close()方法关闭文件,无论在文件使用中遇到什么问题都能安全的退出,即使发生错误,退出运行时环境时也能安全退出文件并给出报错信息。
文件操作语法
“”"
语法:
fp = open(文件,模式,编码集)
fp => 文件的io对象 (文件句柄) _io.BufferedReader
i => input 输入
o => outpur 输出
fp.read() 读取文件内容
fp.write() 写入文件的内容
“”"
文件的io对象是迭代器
1.文件的写入操作
Python write 写文件文件语法语法:
n = file.write(string)
file 表示已经打开的文件对象,string 表示要写入文件的字符串。 函数的返回值 n 是一个 int 类型的整数,表示写入了多少个字节。
在使用 write() 向文件中写入数据,需保证使用 open() 函数是以 r+、w、w+、a 或 a+ 的模式打开文件,否则执行 write() 函数会抛出 io.UnsupportedOperation 错误。
# (1) 打开文件 fp = open("ceshi1.txt",mode="w",encoding="utf-8")# 打开冰箱门 # (2) 写入内容 fp.write("把大象怼进去") # 把大象怼进去 # (3) 关闭文件 fp.close() # 把冰箱门关上
2.文件的读取操作
# (1) 打开文件 fp = open("ceshi1.txt",mode="r",encoding="utf-8") # (2) 读取内容 res = fp.read() #返回读取的文件内容 # (3) 关闭文件 fp.close() print(res)
3.文件存储二进制字节流
“”"
二进制字节流:`用于传输数据或者存储数据的一种数据格式
rb的作用:在读取非文本文件的时候,比如要读取mp3,图像,视频等信息的时候就需要用到rb,
因为这种数据是没办法直接显示出来的
这个字节的模式是用于传输和存储
b"abc" b开头的字节流要求数据只能是ascii编码中的字符,不能是中文。设置中文报错
# 将字符串和字节流(Bytes流)类型进行转换 (参数写成转化的字符编码格式) #encode() 编码 将字符串转化为字节流(Bytes流) #decode() 解码 将Bytes流转化为字符串 """
字节流:
data = b"abc" data = "中文".encode("utf-8") print(data,type(data)) res = data.decode("utf-8") print(res,type(res))
编码后,是字节流,解码后是原数据字符串
# utf-8下 一个中文占用3个字节 data = "中文".encode("utf-8") # 计算字节总大小 print(len(data))
一个中文占三个字节
# 把中字这个字节流进行反解恢复成原来中的字符 "中" res = b"\xe4\xb8\xad".decode() 字符集不写,默认是utf-8 print(res)
###文件存储二进制的字节流
“”“如果存储的是二进制字节流,指定模式wb,不要指定encoding编码集,否则报错”“”
fp = open(“ceshi2.txt”,mode=“wb”)
strvar = “红鲤鱼绿鲤鱼与驴”.encode(“utf-8”)
fp.write(strvar)
fp.close()
write写入的必须是字符串,或字节流
4.文件读取二进制的字节流
fp = open(“ceshi2.txt”,mode=“rb”)
res = fp.read()
fp.close()
print(res)
print(res.decode())
可以直接读取字节流,也可以解码成字符串
5.复制文件
“”“所有的图片,音频,视频都需要通过二进制字节流来进行存储传输.”“”
# 先把原文件的二进制字节流读取出来 # 相对路径找集合.png 相对于当前3.py这个文件 # fp = open("集合.png",mode="rb") # 绝对路径找集合.png 从最底层一级一级往上找 fp = open(r"D:\python32_python\day01\集合.png",mode="rb") res = fp.read() fp.close() # 计算文件中的字节个数 => 文件大小 print(len(res)) # 在把二进制字节流写入到另外一个文件中,相当于复制 fp = open("集合2.png",mode="wb") fp.write(res) fp.close()
查找文件可以使用相对路径,也可以使用绝对路径,相对路径就是相对当前py文件所在路径
将D:\pythonitems\jinghao\test\集合2.png 拷贝到桌面,命名为 集合.png
使用绝对路径时,一般原型化输出字符串,使用元字符串符号 r,防止出现转义
可见已拷贝到桌面
文件操作的扩展模式
各种编码介绍
#(utf-8编码格式下 默认一个中文三个字节 一个英文或符号 占用一个字节)
#read() 功能: 读取字符的个数(里面的参数代表字符个数)
注意:从当前光标往右边读
#seek() 功能: 调整指针的位置(里面的参数代表字节个数)
seek(n)光标移动到n位置,注意: 移动单位是byte,所有如果是utf-8的中文部分要是3的倍数
移动到开头:seek(0,0)
移动到当前位置:seek(0,1)
移动到末尾:seek(0,2)
移动1个汉字:seek(3) 移动光标是按照字节进行移动
seek(0) 把光标移动到文件的开头
seek(0,2) 把光标移动到文件的末尾
#tell() 功能: 当前光标左侧所有的字节数(返回字节数)
tell()
使用tell()可以帮我们获取当前光标在什么位置
1.r+ 先读后写
光标默认在开头位置,文件不存在就报错
""" fp = open("ceshi3.txt",mode="r+",encoding="utf-8") # 先读 res = fp.read() # 在写 fp.write("ab") #写完之后光标在最后,此时如果去读,读不到内容,需要将光标移到开头位置 # 在读 fp.seek(0) # 通过seek把光标移动到开头 print(fp.read()) fp.close() """
2.r+ 先写后读
光标默认在开头位置
fp = open("ceshi3.txt",mode="r+",encoding="utf-8") # 移动光标到最后,否则r模式下,原字符会被覆盖 fp.seek(0,2) # 先写 fp.write("cd") # 把光标移动到文件的开头,然后读取 fp.seek(0) # 在读 res = fp.read() print(res) fp.close()
3.w+ 可读可写,清空重写(默认可以创建新的文件)
文件指针默认在数据开头 即便移动光标到最后,也会清空文件重写
写完之后要想读,需要将指针调整到开头
fp = open("ceshi4.txt",mode="w+",encoding="utf-8") fp.write("abc") fp.seek(0) print(fp.read()) fp.close()
源文件不存在可以创建
4.a+ 可读可写,追加写入 (默认可以创建新的文件)
文件指针默认在数据的末尾
fp = open("ceshi5.txt",mode="a+",encoding="utf-8") fp.write("def") # 读内容 fp.seek(0) print(fp.read()) fp.close()
5.r+和a+区别
r+模式基于当前光标所在位置进行写入覆盖,光标默认在文件开头,但可以调整后,从光标位置开始写
a+模式会强制把光标放到文件末尾进行追加写入,调整光标位置再写不生效,也是从末尾追加 但是读取的时候,移动光标生效
# fp = open("ceshi5.txt",mode="r+",encoding="utf-8") fp = open("ceshi5.txt",mode="a+",encoding="utf-8") fp.seek(3) # 从头数 3个字节的位置 # fp.write("zxc") # 模式会强制把光标放到文件末尾进行追加写入 print(fp.read()) fp.close()
6.seek,tell,read之间的使用
fp = open("ceshi5.txt",mode="r+",encoding="utf-8") fp.seek(4) # tell 当前光标左边所有内容的字节数 res = fp.tell() print(res) # 在r+模式下 read(2) 代表读取2个字符 在rb模式下 read(2) 代表读取2个字节 fp.read(2) # 当前光标往右所有的字符内容 print(fp.tell()) fp.close()
7.注意点 (seek在移动时,有可能移动到某个汉字的字节中间,导致原字节无法解析)
fp = open("ceshi6.txt",mode="r+",encoding="utf-8") fp.seek(3) print(fp.read()) fp.close() # print("你".encode()) # b'\xe4\xbd\xa0'
一般只用到seek(0) 移到文件开始,和seek(0,2)移到文件末尾。
其他位置修改文件不是通过seek来实现的,我们通过read,readline readlines等函数实现
r+与w+啥区别呢,不能简单的理解为读写都可,细节之处略有不同!
r+:先读后写的话是在原有文本后添加, 因为读完后类指针已经在最末尾了,如果是先写后读的话,是从头开始覆盖式写(如只修改了前面的字符,后面字符是不会被删掉的),
类指针停留在写完的末尾,不是文档末尾,可以读出未被覆盖写的部分;
w+:为先写后读,先写完后使用f.seek(0)回到初始位置然后开始读,如果先读的话是读不出任何东西的,因为w+也是纯粹的覆盖写,
在未使用写操作前文档是完全空白的,无论之前该文件里有什么。so ,只能先写后读。
8.with语法 自动实现文件关闭操作
# 方法一.读取二进制字节流 as 取别名 """ with open("集合2.png",mode="rb") as fp: res = fp.read() with open("集合3.png",mode="wb") as fp: fp.write(res) """ # 方法二.继续简化 with open("集合3.png",mode="rb") as fp1 , open("集合4.png",mode="wb") as fp2 : res = fp1.read() fp2.write(res)