文章目录
- 1. 引言
- 2. 基本的文件操作
- 2.1 打开文件
- 2.1.1 mode 访问模式
- 2.1.2 文件不存在,则创建文件
- 2.1.3 二进制打开文件
- 2.1.4 打开文件时,指定编码方式
- 2.2 关闭文件
- 2.2.1 with 打开语句结构
- 2.3 文件的读写
- 2.3.1 写入文件内容
- 2.3.2 读取文件
- 2.3.2.1 read()读取
- 2.3.2.2 readline() 读取一行
- 2.3.2.3 readlines() 读取全部行
- 2.3.3 备份案例的三种方式
- 2.3.3.1 纯文本文件
- 2.3.3.2 二进制文件
- 2.3.3.3 函数备份
- 2.3.4 文件的定位读写
- 2.3.4.1 tell() 方法获取定位
- 2.3.4.2 seek()方法指定位置
- 3. python中os模块
- 3.1 文件和目录,重命名
- 3.1.1 rename() 重命名
- 3.2 文件,删除操作
- 3.3 文件目录,相关操作
- 3.3.1 路径概述
- 3.3.1.1 相对路径
- 3.3.1.2 绝对路径
- 3.3.1.3 拼接路径
- 3.3.2 判断目录和文件,是否存在
- 3.3.3 创建文件(一级和多级)目录
- 3.3.4 删除目录
- 3.3.5 列出目录列表
- 3.3.6 遍历目录内容
- 4.综合案例:
- 4.1 复制并修改文件名
- 4.2 批量修改文件名
1. 引言
- 将数据存储在变量序列和对象中,都是暂时的,程序结束之后就会消失,俗话说“好记性不如烂笔头”,计算机也是如此,一个程序执行之后需要将非常重要的结果,把数据存储起来就非常重要。
- 所以需要将数据,保存在 文件之中 才能永久存储,即使重启电脑,文件中的数据依旧还在,所以python提供了操作文件的对象。
2. 基本的文件操作
2.1 打开文件
- 思考一个问题? 把大象关进冰箱需要几步 ?
- 打开冰箱。
- 把大象放进去。
- 关闭冰箱。
- python中操作文件也同上述案例差不多。
- 新建文件, 或者 打开文件。
- 读 或者 写 数据。
- 关闭文件。
- 文件打开的 语法格式:
open(文件名[ ,访问模式])
- 注意1:文件必须存在,否则会抛出异常。
- 注意2: 文件模式。
''' 文件的打开语法格式: open(文件名[,访问模式]) 文件名 必选参数 访问模式 可选参数 ''' #注意1:文件如果不存在,会抛出异常.FileNotFoundError file = open("D://file.txt") print(file)#<_io.TextIOWrapper name='D://file.txt' mode='r' encoding='cp936'>
2.1.1 mode 访问模式
- 上述案例中,如果使用open函数打开文件时,只传入了文件名, 那么我们 只能读取文件。
- 要想在打开文件中写入数据, 就必须指明文件的 访问模式 。
rb,wb,ab
模式都是以二进制的方式操作文件,通常这几种模式用于处理二进制文件,如:声音,图像,视频等。
访问模式 | 说明 |
---|---|
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
w | 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
w+ | 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
- 需要注意的事项:
r , rb,r+,rb+
文件必须存在。w,wb,w+,wb+
文件存在,则将其覆盖,否则创新文件。
2.1.2 文件不存在,则创建文件
-
打开一个 不存在的文件时,如果不指定访问模式会抛出异常。
FileNotFoundError
-
所以,打开一个文件时,如果文件不存在,需要先创建该文件。
- 需要指定访问模式。指定参数为
w ,w+,a,a+
这样,当打开的文件不存在时,就不会报错,可以新创建文件 (如果存在则覆盖)。
#注意2:文件如果不存在,就会创建新文件,如果存在就覆盖(即使原来有数据). #指定了访问模式 w+ file = open("D://file1.txt",'w+') print(file)#<_io.TextIOWrapper name='D://file1.txt' mode='w+' encoding='cp936'>
- 需要指定访问模式。指定参数为
2.1.3 二进制打开文件
- open()函数不仅可以打开文本,而且还可以 使用二进制形式 打开非文本文件,例如:图片,音频,视频等
- 使用二进制方式打开,如:
rb
- 使用二进制方式打开,如:
#2.打开图片文件以二进制的方式。
file = open('F://01.png','rb')
print(file) #<_io.BufferedReader name='F://01.png'>
2.1.4 打开文件时,指定编码方式
-
纯文本文件 的编码格式有很多,有
gbk,utf-8
等。- 在打开文本文件时 也可以指定编码格式`
encoding=' 编码格式'
-
open()
函数默认的是gbk
编码, 所以当读取时utf-8
的文本文件会乱码。
#2.打开文本文件open()默认的编码格式是gbk file = open('D://01.txt','r').read() print(file)
-
读的结果,所以需要读时设置编码格式。
file = open('D://01.txt','r',encoding='utf-8').read() print(file)
2.2 关闭文件
-
打开的文件,切记要使用close方法关闭。即使文件会在程序退出后自动关闭,但是考虑到数据的安全性,在每次使用完文件之后,都要使用close方法关闭文件,为什么要关闭?
- 因为一旦程序崩溃很可能导致文件中的数据没有保存。
-
close()
方法先刷新缓冲区中还有写入的信息, 然后再关闭文件,这样可以将没有写入文件的内容写入文件中。在关闭文件后,就不能进行写入操作了。#close关闭文件操作 file = open('D://01.txt','w') file.close()#关闭文件
2.2.1 with 打开语句结构
-
打开文件后,要及时将其关闭。如果忘记关闭可能会带来意向不到的问题,所以为了避免类似事情发生,在python中使用with语句打开文件。
with open('filename') as file: with-body
file
是open
的内容保存到file
变量中。- 其中的
with-body
:用于指定with
语句体,可以执行一些相关的操作,如下操作。
with open('D://01.txt',mode='r') as file: data = file.read() #使用file读取文件 print(data)
2.3 文件的读写
2.3.1 写入文件内容
-
文件最重要的能力就是 接收数据或者提供数据。
- 文件的读写,无非是将数据写入文件或者从文件中读取数据。
-
向文件中写入数据,需要使用
write
方法完成。- 在操作某个文件时,每调用一次write方法,写入的数据就 会追加到文件末尾。
-
操作步骤
- 打开文件
- 写入数据
- 刷新数据
- 关闭文件
#打开文件,访问模式 w准备写 file = open('D://01.txt','w') # 写数据 file.write("你好,周杰伦") file.write("\n") #换行 file.write("你的歌曲,夜曲") #刷新文件flush(),之后的流还可以使用。 file.flush() file.write("暗号") file.close() #file.write("七里香")#ValueError: I/O operation on closed file.
- 访问模式是
mode 为 w
就是如果存在就覆盖,不存在就创建。
2.3.2 读取文件
2.3.2.1 read()读取
- 文件对象提供了read()方法读取,语法格式:
- 下列方法中的
size
表示要从文件中读取的数据长度,单位为字节。如果没有指定size, 那么就表示 读取文件的全部数据。
file.read(size)
- 下列方法中的
- 注意在底层编码是不同的一个汉字和一个英文,但是在字符串中,使用
read(1)
时,读取汉字和英文都视为一个字节。#r+读写, r只读 with open('D://01.txt',mode='r+') as file: data = file.read(1)#读取第一个字符. print(data)
2.3.2.2 readline() 读取一行
-
在使用read()方法读取文件时,如果文件很大,一次读取全部内容到内存,容易造成内存不足,所以通常会采用逐行读取。
- 文件对象提供了
readline()
方法用于每次读取一行数据。
file.readline()
- 文件对象提供了
-
每次读取一行。
- 这样会发现一个问题,只能读一行。
with open('d://01.txt',mode='r') as file: data = file.readline() print(data)
-
怎么解决每次只读一行的问题 ?
readline()
方法 如果没有读取,返回空字符串,循环结束。
#第一种方式使用while循环方式
with open('d://01.txt',mode='r') as file:
line = file.readline()
#readline()会返回下一行
while line:
print(line)
#继续读取下一行
line = file.readline() #步长
print("-"*40)
# 第二种处理方式使用for循序的方式
with open('d://01.txt',mode='r') as file:
for line in file:
print(line)
2.3.2.3 readlines() 读取全部行
- 同
read()
不使用size一样, 读取全部,但是 不同处在于 返回的是一个列表。#返回的是一个列表 with open('d://01.txt',mode='r') as file: data = file.readlines() print(data)
- 这样相当于同
read()
读取的方法一样了。- 所以,用
readline()
一样,使用循环读取。
with open('d://01.txt', mode='r') as file: data = file.readlines()#返回一个列表 for i in data: #遍历列表 print(i)
- 所以,用
2.3.3 备份案例的三种方式
- 在实际操作中,文件的 读写可以已完成很多功能,像 文件的备份 就是文件的读写功能的应用。
- 需求, 读取一个文件内容,将文件写入到另一个磁盘中进行备份,相当于文件的 Ctrl+C ,Ctrl+V。
2.3.3.1 纯文本文件
- 第一种备份情况,使用读写操作进行。
- 如果是纯文本文件,需要注意使用 读写编码,使用同一个文本格式。
''' 1.原生读写备份 1.源文件-->备份文件 2.目的文件 注意编码: 如果是存文本格式,同一使用 r和 w 同一使用编码格式,encoding='utf-8' ''' #源文件 old_file="D://三年级上.txt" #目的文件 new_file="D://backup_三年级上.txt" #打开源文件,r 只读 with open(old_file,mode='r',encoding='utf-8') as source: #读取源文件 data = source.read() #创建文件进行写入 w 文件不存在就创建. with open(new_file,mode='w',encoding='utf-8') as target: target.write(data) print("文件写入成功!")
2.3.3.2 二进制文件
-
如果备份视频,图片,就需要使用二进制读写,上述的纯文本形式就不能实现了。
- 访问模式 就需要使用二进制
rb 和 wb
。 - 二进制就不需要 使用编码格式
encoding='gbk'
可以省略。
''' 2. 备份视频,图片等. ''' # 源文件,压缩文件 old_file = "D://day06.rar" # 目的文件 new_file = "D://backup_day06.rar" # 以二进制方式打开源文件,省略编码格式 encoding='utf-8' with open(old_file, mode='rb') as source: # 读取源文件 data = source.read() # 创建文件进行写入 wb文件不存在就创建. with open(new_file, mode='wb') as target: target.write(data) #最后提示程序 print("以二进制形式备份成功!")
- 访问模式 就需要使用二进制
2.3.3.3 函数备份
- 在之前我们学过函数了,写程序设计需要封装方法,接下来备份程序使用函数操作。
- 将上述代码封装到函数中。
''' 封装函数万能备份. ''' def backup_file(old_file,new_file): # 以二进制方式打开源文件,省略编码格式 encoding='utf-8' with open(old_file, mode='rb') as source: # 读取源文件 data = source.read() # 创建文件进行写入 wb文件不存在就创建. with open(new_file, mode='wb') as target: target.write(data) #最后提示程序 print("备份成功!") #函数调用 a = "D://三年级下.txt" b = "D://back_up_三年级下.txt" #传递参数 backup_file(a,b)
- 使用python自带的函数
copytree()
方法进行备份。
import shutil #导入python自带函数库 a = "D://01" b = "D://01_backup" #可以复制文件夹,及其子目录 shutil.copytree(a,b) print("执行完毕")
2.3.4 文件的定位读写
- 文件的读写都是从文件的头开始,到文件的尾巴结束,但是在实际的开发中,可能需要从文件的某个特定位置开始读写,这时候就需要对文件的读写位置进行定位
tell()
用于 获取当前位置,seek()
用于 设置新的位置。- 它们一起使用,可以使我们在文件处理过程中 自由地控制和定位文件指针的位置。
2.3.4.1 tell() 方法获取定位
-
在文件的读写过程中,想知道文件读取到了 文件的哪个位置, 则可以使用
tell()
方法来获取,- 该方法会返回文件的指针的当前内容。
abcdefgabcdefg
- 每次的读取位置都会累计,直到读取最大长度为止。
''' 1.文件定位读写 abcdefgabcdefg ''' # 打开一个文件 with open("D://02.txt", mode='r', encoding='utf-8') as file: data = file.read(5)#read(size) print(data) position = file.tell() print(position) data = file.read(10) #最大长度就是14个 超过就按最大算 print(data) # 查找当年位置 position = file.tell() print(position)
- 输出结果
abcde 5 fgabcdefg 14
- 该方法会返回文件的指针的当前内容。
2.3.4.2 seek()方法指定位置
- 如果要从指定的位置开始读取或者写入文件上的数据,则使用seek() 方法实现。
- 可以指定开始的位置。
''' 1.文件定位读写 ''' # 打开一个文件 with open("D://02.txt", mode='r', encoding='utf-8') as file: data = file.read(10)#read(size) print(data) position = file.tell() print(position) print("-"*40) #华丽的分割线 #从新定位在第8个字符 file.seek(8) #定位之后从新获取,从第8个开始在读3个字符 data2 =file.read(3) print(data2) position = file.tell() print(positio
-
输出结果:
abcdefgabc 10 ---------------------------------------- bcd 11
3. python中os模块
- python中的内置os模块除了可以对 目录进行操作,还可以对文件 进行一些高级操作:
- 具体常用函数如下:
函数 | 说明 |
---|---|
remove(path) | 删除path指定的文件路径 |
rename(src,dst) | 将文件或目录src,重命名为dst |
stat(path) | 返回path指定文件信息 |
mkdir(path) | 创建一个新文件目录 |
getcwd() | 返回当前工作目录 |
abspath() | os.path 模块提供,用于获取文件或者目录的绝对路径 |
exists() | os.path 模块提供,判断文件夹是否存在 |
rmdir() | os 模块提供,删除为空的最后一级文件目录 |
listdir(path) | os 模块提供,列出当前目录列表。 |
3.1 文件和目录,重命名
os 模块
是 Python 中用于与操作系统进行交互的标准库模块,通过 os 模块, 程序中执行系统命令、访问环境变量、操作文件和目录等。
3.1.1 rename() 重命名
-
OS 模块 中提供的 重命名文件和目录
rename(src,dst)
的函数。- 注意1: 如果是指定的路径,是文件,则重命名文件,如果指定的,是目录,则重命名目录。
-
重命名目录和文件名。
- 使用前注意导入库,
import os
。 - 如果 修改的源文件不存在,则抛出异常
FileNotFoundError: [WinError 2] 系统找不到指定的文件。
import os # 使用os模块 # 指定文件 os.rename("D://python.txt", "D://python_修改.txt") # 指定目录 os.rename("D://python", "D://python_修改") print("执行成功")
- 使用前注意导入库,
3.2 文件,删除操作
- OS模块中的remove()操作可以对文件进行移除。
- 使用时需要先导入函数模块
import os
os.remove("D://python_修改.txt") print("移除成功")
- 使用时需要先导入函数模块
3.3 文件目录,相关操作
3.3.1 路径概述
- 用于定位一个 文件或者目录的字符串 被称为一个路径,通常路径有两种:
- 相对路径,通常使用的 一些符号及其符号所代表的意义 概述如下:
- “./”:表示当前的文件所在的目录。
- “…/”:表示当前的文件所在的上一层的目录。
- “/”:表示当前的文件所在的根目录。
- 绝对路径,指文件具体的物理位置
C://user/root/1.txt
- 相对路径,通常使用的 一些符号及其符号所代表的意义 概述如下:
3.3.1.1 相对路径
- 如何理解相对路径,可以通过我们操作pycharm工程中的文件来举例子:
- 例如:在工程中 创建一个1.txt文件,其实该文件的 绝对路径 在
D://commsoft/pythonprogect/day01/1.txt
,但是我们在工程中只需要使用相对路径即可访问。 - 输出当前目录
print(os.getcwd())
,注意到如 OS 模块。
- 例如:在工程中 创建一个1.txt文件,其实该文件的 绝对路径 在
3.3.1.2 绝对路径
- 绝对路径是指在使用文件时指定的实际路径,它不依赖当前的工作目录,使用
os.path 模块提供的adspath()
方法。- 使用
os.path.asbpath(path)
#返回绝对路径,os.path.asbpath(path) with open("../1.txt", encoding="utf-8") as file: data = file.read() # 我是周杰伦 print(os.path.abspath("../1.txt")) #D:\commonSoft\fileproject\1.txt print(data)
- 使用
3.3.1.3 拼接路径
-
使用
os.path.join()
拼接路径的好处就是可以正确的处理不同路径之间的分隔符。- 如果直接使用+ 号连接两个路径中奖必须使用分隔符+“/” , 但是如果使用拼接os.path.join(),就可以省略考虑连接问题。
- 以下为代码片段
print(file_path+file_name) print(file_path+new_name) print("-"*40) print(os.path.join(file_path,file_name)) print(os.path.join(file_path,new_name))
- 输出结果:
D:/记录表[吴琼老师]-新建文本文档 - 副本 (3).txt D:/记录表[吴琼老师]-[吴琼老师]-新建文本文档 - 副本 (3).txt D:/记录表\[吴琼老师]-新建文本文档 - 副本 (2).txt D:/记录表\[吴琼老师]-[吴琼老师]-新建文本文档 - 副本 (2).txt
3.3.2 判断目录和文件,是否存在
-
在实际程序开发中,需要对文件夹进行一些操作,如新建文件夹,但是在新建之前需要判断,该目录是否存在。
- 需要使用
os.path
模块中的exists(path)
方法。
import os #使用 os.path 模块中的 exists()方法 a = os.path.exists("D://os创建") print(a) #如果存在返回True反之 false
- 需要使用
-
如果将判断的目录该为文件,就可以判断文件是否存在。
import os #使用 os.path 模块中的 exists()方法,可以用于判断文件是否存在 a = os.path.exists("D://python.pdf") print(a) #如果存在返回True反之 false
3.3.3 创建文件(一级和多级)目录
-
如何创建一个文件目录,os模块中给出了两个创建目录的函数,一个用于创建一级目录,另一个用于创建多级目录
- 创建单级目录,使用
mkdir(path)
##1.使用os模块进行创建os.mkdir() # a = os.mkdir("D://os创建") # #FileExistsError: [WinError 183] # print(a) #如果存在则会报异常 #2.所以在创建时需要判断exists()方法使用 if not os.path.exists("D://os创建"): #不存在则创建 os.mkdir("D://os创建") print("目录创建成功") else: print("该目录已经存在")
- 创建单级目录,使用
-
如何创建多级目录,需要使用os模块中的
makedirs(path)
函数。import os #导入模块os #判断文件夹是否存在 if not os.path.exists("D://1//2//3"): os.makedirs("D://1//2//3") print("创建成功") else: print("文件已创建")
3.3.4 删除目录
- os模块的中提供了删除目录的方式。
- 只能删除 为空的目录,删除时 记得判断目录。
import os if os.path.exists("D://1//2//3"): #如果存在则删除,只能删除为空目录 os.rmdir("D://1//2//3")#删除//3目录 print("删除成功") else: print("目录不存在")
- 如果想删除多级目录怎么办?
- 则需要使用
shutil模块中的函数rmtree()
,谨慎使用。
import shutil # 导入shutil模块 # 该操作谨慎使用。 shutil.rmtree("D://1") #将D盘 1文件和子目录都删除掉 print("删除成功")
- 则需要使用
3.3.5 列出目录列表
- 显示当前目录中的内容,只能显示当前级。
- 相当于列出同级列表中的内容,如windows 中的dir
#列出D:// 目录下 , 所有内容. a = os.listdir("D://") print(a)
3.3.6 遍历目录内容
-
遍历同循环有相同的意思,输出该目录和子目录中所有内容。
- 使用os模块中的 walk()函数。
import os data = os.walk("D://1") print(type(data),data)#<generator object walk at 0x000001EFDEA5BBA0> #需要遍历输出内容 for i in data: print(i) #循环遍历每一级目录,并输出目录中内容.
-
在生成器对象上进行循环遍历时,可以使用多个变量来接收生成器对象返回的内容。os.walk()函数每次返回三个值, 分别是
-
当前目录路径、当前目录下的所有子文件夹名称列表、当前目录下的所有文件名称列表。通过使用三个变量(i, j, k)来接收这三个值,对应的意义如下:
- 变量 i:当前目录路径,即根目录路径。
- 变量 j:当前目录下的所有子文件夹名称列表。
- 变量 k:当前目录下的所有 文件名 称列表。
import os data = os.walk("D://1") print(type(data), data) # <generator object walk at 0x000001EFDEA5BBA0> # 需要遍历输出内容,使用os.path.join拼接字符串 for i, j, k in data: # 显示目录 for a in j: print(os.path.join(i, a)) # 显示具体文件 for a in k: print(os.path.join(i, a))
-
4.综合案例:
4.1 复制并修改文件名
- 要求复制文件,并且从新命名,命名为 : 复制_源文件名称。
- 提示1: 涉及一个拼接文件名称操作。
- 提示2: 截取源文件名称操作。
#备份方法 def backup(old_file): #打开文件. with open(old_file, mode='rb') as file_old: data = file_old.read() #读取文件 if old_file:#判断文件是否为空 file_name = old_file.rfind(".") # 找文件中.从后面找第一个出现 if file_name > 0: #判断长度. file_type = old_file[file_name:] #切片[start:)截取文件类型 # 拼接新文件: 文件名old_file[:file_name]+_复制_+文件类型 new_file = old_file[:file_name]+ "--复制" + file_type with open(new_file, mode='wb') as file_new: file_new.write(data) # 将旧文件内容写入到新文件中. return True # 调用方法 backup("D://三年级下.txt")
4.2 批量修改文件名
-
如果一个个单独修改文件名,修改的文件如果很多,则效率显然是底下的,这时我们就需要借助刚学习的文件操作,编写一个批量修改的小程序。
-
假设现在有一批文件的名称需要批量修改,查看下列修改前后的对比。
import os file_path = "D:/记录表" # 操作文件路径 dir_list = os.listdir(file_path) # 显示文件路径 # 遍历所有文件名称 for file_name in dir_list: # 创建一个标识,根据标志进行操作. new_name = '[吴琼老师]-' + file_name #1.拼接路径, # old_file = file_path+"\\"+ file_name # 源文件路径 # new_file = file_path+"\\"+ new_name # 新文件路径 #2.也可以使用拼接字符串os.path.join() old_file = os.path.join(file_path,file_name) new_file = os.path.join(file_path,new_name) #重命名 os.rename(old_file,new_file)