Python文件和目录操作
创建目录
1、os.makedirs 可以递归的创建目录结构
例如:
import os
os.makedirs('路径(可以是相对路径也可以是绝对路径)',exist_ok=True)
exist_ok=True 指定了,如果某个要创建的目录已经存在,也不报错
2、mkdir()函数用于在当前目录下创建目录
例如:
import os
os.mkdir('目录名')
删除目录
1、rmdir()函数用于删除目录
例如:
import os
os.rmdir('test')
2、shutil.rmtree() 可以递归的删除某个目录所有的子目录和子文件
import shutil
shutil.rmtree('tmp', ignore_errors=True)
注意:参数 ignore_errors=True 保证如果目录不为空,不会抛出异常。
拷贝目录
如果我们要拷贝一个目录里面所有的内容(包括子目录和文件、子目录里面的子目录和文件,等等)到另外一个目录中,可以使用 shutil的copytree函数。
from shutil import copytree
# 拷贝 d:/tools/aaa 目录中所有的内容 到 e:/bbb 中
copytree('d:/tools/aaa', 'e:/new/bbb')
注意拷贝前, 目标目录必须 不存在 ,否则会报错。
上面的代码执行前面,如果 e:/new/bbb 已经存在,执行到copytree时,就会报错
上面的代码执行前面,如果 e:/new 这个目录都不存在,执行到copytree时,就会 创建 e:/new 目录,再创建 e:/new/bbb 目录,再拷贝 d:/tools/aaa 目录中所有的内容 到 e:/new/bbb 中。
上面的代码执行前面,如果 e:/new 这个目录存在,但是 e:/new/bbb 不存在,执行到copytree时,就只会 创建 e:/new/bbb ,再拷贝 d:/tools/aaa 目录中所有的内容 到 e:/new/bbb 中。
拷贝文件
shutil 模块里面有很多 目录文件操作的函数
拷贝文件,可以使用shutil模块的copyfile函数。
from shutil import copyfile
# 拷贝 d:/tools/first.py 到 e:/first.py
copyfile('d:/tools/first.py', 'e:/first.py')
注意,如果拷贝前,e:/first.py 已经存在,则会被拷贝覆盖,所以使用该函数一定要小心。
删除文件
os.remove 可以删除一个文件
import os
os.remove('sdf.py')
打开文件
在Python中可通过内置函数open()打开文件,该函数的语法格式如下:
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
参数说明:
file: 必需,文件路径(相对或者绝对路径)。
mode: 可选,文件打开模式
buffering: 设置缓冲
encoding: 用于指定文件的编码格式,常见的编码格式有ascii、utf-8等;一般使用utf8
errors: 报错级别
newline: 区分换行符
closefd: 传入的file参数类型
opener:通过传递可调用对象opener可以使用自定义开启器。然后通过调用opener(文件,标志)获取文件对象的基础文件描述器。opener必须返回一个打开的文件描述器(传递os.open为opener 结果类似的功能 None)。 【一般用不到】
参数mode用于设置文件的打开模式,常用的打开模式有r、w、a。
- r:以只读的方式打开文件,参数mode的默认值。
- w:以只写的方式打开文件。
- a:以追加的方式打开文
以上模式可以单独使用,也可以与模式b、模式+搭配使用。其中,模式b表示以二进制方式打开文件,模式+表示以更新的方式打开文件。常用的文件打开模式及其搭配如下:
若open()函数调用成功,返回一个文件对象,示例如下:
file1 = open('E:\\a.txt') # 以只读方式打开E盘的文本文件a.txt
file2 = open('b.txt', 'w') # 以只写方式打开当前目录的文本文件b.txt
file3 = open('c.txt', 'w+') # 以读/写方式打开当前目录的文本文件c.txt
file4 = open('d.txt', 'wb+') # 以读/写方式打开当前目录的二进制文件d.txt
以只读模式打开文件时,若待打开的文件不存在,文件打开失败,程序会抛出异常。假设以上代码打开的文件a.txt不存在,具体异常信息如下:
Traceback (most recent call last):
File "E:\python_study\first_proj\test.py", line 1, in <module>
file1 = open('E:\\a.txt')
FileNotFoundError: [Errno 2] No such file or directory: 'E:\\a.txt'
关闭文件
在Python中可通过close()方法关闭文件,也可以使用with语句实现文件的自动关闭。
(1)close()方法
file.close()
(2)with语句
当打开与关闭之间的操作较多时,很容易遗漏文件关闭操作,为此Python引入with语句预定义清理操作、实现文件的自动关闭。
with open('a.txt') as f:
pass # 一些操作
以上示例中as后的变量f用于接收with语句打开的文件对象。程序中无须再调用close()方法关闭文件,文件对象使用完毕后,with语句会自动关闭文件。
为什么要及时关闭文件?
虽然程序执行完毕后,系统会自动关闭由该程序打开的文件,但计算机中可打开的文件数量是有限的,每打开一个文件,可打开文件数量就减1;打开的文件占用系统资源,若打开的文件过多,会降低系统性能;当文件以缓冲方式打开时,磁盘文件与内存间的读写并非即时的,若程序因异常关闭,可能产生数据丢失。因此,在编写代码时应在程序中主动关闭不再使用的文件。
读取文件
(1)read()方法
read()方法可以从指定文件中读取指定字节的数据,其语法格式如下:
read(n=-1)
以上格式中的参数n用于设置读取数据的字节数,若未提供或设置为-1,则一次读取并返回文件中的所有数据。
使用示例:
with open('file.txt', mode='r') as f:
print(f.read(2)) # 读取2个字节的数据
print(f.read()) # 读取剩余的全部数据
假设file.txt文件中的内容如下:
运行代码,结果如下所示:
(2)readline()方法
readline()方法可以从指定文件中读取一行数据,其语法格式如下:
readline()
(3)readlines()方法
readlines()方法可以一次性读取文件中的所有数据,若读取成功返回一个列表,文件中的每一行对应列表中的一个元素。readlines()方法的语法格式如下:
readlines(hint=-1)
以上格式中,参数hint的单位为字节,它用于控制要读取的行数,如果行中数据的总大小超出了hint字节,readlines()不会读取更多的行。
ps:以上介绍的3个方法中,read()(参数缺省时)和readlines()方法都可一次读取文件中的全部数据,但因为计算机的内存是有限的,若文件较大,read()和readlines()的一次读取便会耗尽系统内存,所以这2种操作都不够安全。为了保证读取安全,通常多次调用read()方法,每次读取n字节的数据。
写文件
(1)write()方法
write()方法可以将指定字符串写入文件,其语法格式如下:
write(data)
以上格式中的参数data表示要写入文件的数据,若数据写入成功,write()方法会返回本次写入文件的数据的字节数。
(2)writelines()方法
writelines()方法用于将行列表写入文件,其语法格式如下:
writelines(lines)
以上格式中的参数lines表示要写入文件中的数据,该参数可以是一个字符串或字符串列表。需要说明的是,若写入文件的数据在文件中需要换行,应显式指定换行符。
使用writelines()方法向文件write_file.txt中写入数据,示例代码如下:
string = "Here we are all, by day;\nby night we're hurl'd By dreams, " \
"each one into a several world."
with open('write_file.txt', mode='w', encoding='utf-8') as f:
f.writelines(string)
运行代码,若没有输出信息,说明字符串被成功地写入文件。
ps: 字符与编码
文本文件支持多种编码方式,不同编码方式下字符与字节的对应关系不同,常见的编码方式以及字符与字节的对应关系如下表所示。
修改文件名、目录名
要修改文件名、目录名,可以使用os模块的rename函数。
import os
# 修改目录名 d:/tools/aaa 为 d:/tools/bbb
os.rename('d:/tools/aaa','d:/tools/bbb')
# 修改文件名 d:/tools/first.py 为 d:/tools/second.py
os.rename('d:/tools/first.py','d:/tools/second.py')
注意,Linux 系统上,如果重命名之前 d:/tools/second.py 已经存在,则会被覆盖,所以使用该函数一定要小心。
判断文件、目录是否存在
如果我们需要判断一个指定路径的文件或者目录是否存在,可以使用下面的方法
import os
os.path.exists('d:/systems/cmd.exe')
os.path.exists('d:/systems')
exists方法返回值为True表示 存在,否则表示不存在。
如果你要判断指定路径是否是文件
import os
# 返回值为True 表示是文件
os.path.isfile('d:/systems/cmd.exe')
如果你要判断指定路径是否是目录
import os
# 返回值为True 表示是目录
os.path.isdir('d:/systems')
获取当前目录
当前目录即Python当前的工作路径。os模块中的getcwd()函数用于获取当前目录,调用该函数可获取当前工作目录的绝对路径。
print(os.getcwd())
更改默认目录
os模块中的chdir()函数用于更改默认目录。若在对文件或文件夹进行操作时传入的是文件名而非路径名,Python解释器会从默认目录中查找指定文件,或将新建的文件放在默认目录下。若没有特别设置,当前目录即为默认目录。
使用chdir()函数更改默认目录为“E:\”,再次使用getcwd()函数获取当前目录,示例代码如下:
os.chdir('E:\\') # 更改默认目录为E:\
print(os.getcwd()) # 获取当前工作目录
获取文件名列表
实际应用中常常需要先获取指定目录下的所有文件,再对目标文件进行相应操作。os模块中提供了listdir()函数,使用该函数可方便快捷地获取指定目录下所有文件的文件名列表。
dirs = os.listdir('./') # 获取文件名列表
print(dirs) # 打印获取到的文件名列表
递归的遍历目录下面所有的文件
我们要得到某个目录下面所有的子目录 和所有的文件,存放在两个列表中
import os
# 目标目录
targetDir = r'd:\tmp\util\dist\check'
files = []
dirs = []
# 下面的三个变量 dirpath, dirnames, filenames
# dirpath 代表当前遍历到的目录名
# dirnames 是列表对象,存放当前dirpath中的所有子目录名
# filenames 是列表对象,存放当前dirpath中的所有文件名
for (dirpath, dirnames, filenames) in os.walk(targetDir):
files += filenames
dirs += dirnames
print(files)
print(dirs)
如果要得到某个目录下所有文件的全路径可以这样
import os
# 目标目录
targetDir = r'd:\tmp\util\dist\check'
for (dirpath, dirnames, filenames) in os.walk(targetDir):
for fn in filenames:
# 把 dirpath 和 每个文件名拼接起来 就是全路径
fpath = os.path.join(dirpath, fn)
得到目录中所有的文件和子目录名
import os
# 目标目录
targetDir = r'd:\tmp\util\dist\check'
files = os.listdir(targetDir)
print(files)
如果我们只需要获取目录中所有的文件,或者只需要子目录,可以这样
import os
from os.path import isfile, join,isdir
# 目标目录
targetDir = r'd:\tmp\util\dist\check'
# 所有的文件
print([f for f in os.listdir(targetDir) if isfile(join(targetDir, f))])
# 所有的目录
print([f for f in os.listdir(targetDir) if isdir(join(targetDir, f))])
得到目录中指定扩展名的文件和子目录
import glob
exes = glob.glob(r'd:\tmp\*.txt')
print(exes)