资源操作之文件和目录操作
1. 基础操作
- 打开文件
open(file, mode=‘r’, buffering=None, encoding=None, errors=None, newline=None, closefd=True)函数有很多参数,只有file参数是必需的,常用的是file,mode,encoding,分别表示:- file:文件描述符,表示要打开的文件;
- mode:指定文件打开的模式,包含r(只读)、w(只写)、a(追加),还有b、t、+字符可以与文件打开模式组合使用,分别表示二进制模式、文本模式、读写模式;
- encoding:表示返回的数据采用的编码,默认为utf-8;
还有一些不常用的参数:
- buffering:取值有0,1,>1三个。
0代表缓冲关闭(只适用于二进制模式);
1代表行缓冲(只适用于文本模式);
>1的整数指定缓冲区的大小;
不指定时,文本文件采用行缓冲,二进制文件采用固定大小的块缓冲; - errors:此参数不应在二进制模式下使用,取值有strict和ignore。
当取strict时,字符编码出错会报错;
当取ignore时,字符编码出错,程序会忽略,继续执行下面的程序; - newline:只对文本模式有效,取值有None、\n、\r、’’、’\r\n’。
1)在输入时:
取值为None时,使用通用换行符(\n、\r、’’、’\r\n’),并且返回时转换为\n;
取值为’‘时,在输入时使用通用换行符(\n、\r、’’、’\r\n’),但是不经转换直接返回;
如果’‘中定义了值,则以该值为换行符,并返回给调用者;
2)在输出时:
如果换行为None,则写入的任何’\n’字符都将转换为系统默认行分隔符os.linesep;
如果换行符是’‘或’\n’,则不会进行翻译;
如果换行符是任何其他合法值,则写入的任何’\n’字符都将转换为给定的字符串; - closefd:与传入的文件参数有关,默认情况下为True,传入的file参数为文件的文件名;取值为False的时候,file只能是文件描述符;
推荐写法: 使用Python3的标准库,内置函数open()
- 如果当前目录中存在要打开的文件,则直接将文件作为参数即可;
- 如果文件位于其他地方,可指定完整路径;
- 如果指定的文件不存在,会引发异常:FileNotFoundError
# 显式地指定二进制读取模式,获取可读取的文件对象,默认编码模式为utf-8
f = open("pythonCodingGuide/test.py", "rb", encoding="utf-16")
# 指定写入模式,在文件存在时写入文件,不存在时创建文件
f = open("pythonCodingGuide/test.py", "w")
# 指定独占写入模式,在文件已经存在时引发异常:FileExistsError
f = open("pythonCodingGuide/test.py", "x")
# 在写入模式下打开文件时,既有内容将被删除(截断),并从文件开头处开始写入
# 此时可以使用附加模式,不截断,直接在既有文件末尾继续写入
f = open("pythonCodingGuide/test.py", "a")
# '+'可以与其他模式结合使用,表示既可读取也可写入
# 注意:'r+''w+'之间有个重要差别,后者截断文件,前者不会
f = open("pythonCodingGuide/test.py", "r+")
f = open("pythonCodingGuide/test.py", "w+")
1) 关闭资源
python中打开的资源使用完毕后,引用计数垃圾回收,会自动关闭,但是如果出现异常而又没有手动关闭资源,可能会引发一些问题:
- 相关数据结构会占用内存;
- 在进程退出之前,文件无法删除;
- 系统会缓存写入文件的内容,然后慢慢写入文件,如果中途出现异常会丢失,正常关闭资源会将缓存中的内容写入文件;
推荐写法: 使用Python3的标准库,with语句打开资源
- 将需要打开的文件放在with语句中,这样with语句就会自动关闭文件,不管程序执行中是否产生异常
- 使用 with语句管理的资源必须是一个实现上下文管理协议的类,这个类的对象可被称为上下文管理器
filename = 'pythonCodingGuide/test.py'
with open(filename, 'r') as fd:
"""do something"""
# with语句也可以处理通过fileinput.input合并的多个文件
import fileinput
with fileinput.input(files=('test.txt', 'info.txt')) as f:
"""do something"""
一般写法: 使用Python3的标准库,在try-finally语句中使用close()函数显式的关闭
- 使用finally语句是为了确保程序能够去执行关闭资源的操作,但当finally语句中出现异常时,资源仍有可 能无法正常关闭
f = open('pythonCodingGuide/test.py')
try:
"""do something"""
finally:
"""do something""" # 若此处出现异常,资源没有正常关闭
f.close()
2. 文件修改
1) 重命名文件
重命名文件
推荐写法: 使用Python3的标准库,os模块的os.rename()函数
- 需要导入os模块
- 当指定的文件不存在时,会引发异常:FileNotFoundError
- 当新的文件名已经存在时,会引发异常:FileExistsError
import os
os.rename("old_file_name", "new_file_name")
一般写法: 使用Python3的标准库,shutil模块的shutil.move()函数
- 需要导入shutil模块
- 当指定的文件不存在时,会引发异常:FileNotFoundError
- 当新的文件名已经存在时,会覆盖原来的文件
import shutil
shutil.move("old_file_name", "new_file_name")
2) 修改文件权限
更新文件权限
推荐写法: 使用Python3的标准库,os模块的chmod()函数
- 需要导入os模块以及stat模块
import os
import stat
# 添加owner权限
os.chmod("test.txt", stat.S_IRWXU) # owner拥有全部权限
os.chmod("test.txt", stat.S_IXUSR) # owner拥有执行权限
os.chmod("test.txt", stat.S_IWUSR) # owner拥有写权限
os.chmod("test.txt", stat.S_IRUSR) # owner拥有读权限
# 添加group权限
os.chmod("test.txt", stat.S_IRWXG) # group拥有所有权限
os.chmod("test.txt", stat.S_IRGRP) # group拥有读权限
os.chmod("test.txt", stat.S_IWGRP) # group拥有写权限
os.chmod("test.txt", stat.S_IXGRP) # group拥有执行权限
# 添加其他用户权限
os.chmod("test.txt", stat.S_IRWXO) # 其他用户拥有全部权限
os.chmod("test.txt", stat.S_IROTH) # 其他用户拥有读权限
os.chmod("test.txt", stat.S_IWOTH) # 其他用户拥有写权限
os.chmod("test.txt", stat.S_IXOTH) # 其他用户拥有执行权限
# 同时添加多个权限
os.chmod("test.txt", stat.S_IRWXU | stat.S_IRWXO | stat.S_IRWXG) # mod:777
3. 文件删除
1) 删除文件
删除指定的文件
推荐写法: 使用Python3的标准库,os模块的os.remove()函数
- 需要导入os模块
- 当删除的目标文件不存在时,引发异常:FileNotFoundError
- 当删除的文件正在使用时,引发异常
import os
os.remove("test.txt") # 文件存在且不被占用时,成功删除文件
# 当删除目标不是文件时,引发异常
os.remove("python/test") # 目标是目录,引发异常:PermissionError
推荐写法: 使用Python3的标准库,os模块的os.unlink()函数
- 需要导入os模块
- 当删除的目标文件不存在时,引发异常:FileNotFoundError
- 当删除的文件正在使用时,引发异常
import os
os.unlink("test.txt") # 文件存在且不被占用时,成功删除文件
# 当删除目标不是文件时,引发异常
os.unlink("python/test") # 目标是目录,引发异常:PermissionError
2) 删除目录
删除指定的目录,目录必须是空目录,否则删除失败
推荐写法: 使用Python3的标准库,os模块的os.rmdir()函数
- 需要导入os模块
import os
# 删除存在的空目录
os.rmdir("python/test")
# 删除的目录不存在时
os.rmdir("java/test") # 引发异常:FileNotFoundError
# 删除的目录非空时
os.rmdir("PythonCodingGuide/doc") # 引发异常:OSError: [WinError 145] 目录不是空的
推荐写法: 使用Python3的标准库,os模块的os.removedirs()函数
- 需要导入os模块
- 子目录成功删除时,会删除空的父目录
import os
# 删除存在的空目录
os.removedirs("python/test")
# 删除的目录不存在时
os.removedirs("java/test") # 引发异常:FileNotFoundError
# 删除的目录非空时
os.removedirs("PythonCodingGuide/doc") # 引发异常:OSError: [WinError 145] 目录不是空的
3) 删除目录及其文件和子目录
删除目录及其文件和子目录
推荐写法: 使用Python3的标准库,shutil模块的shutil.rmtree()函数
- 需要导入shutil模块
import shutil
# 删除存在的目录
shutil.rmtree("python/test")
# 删除的目录不存在时,引发异常
shutil.rmtree("java/test") # 引发异常:FileNotFoundError
一般写法: 使用Python3的标准库,os模块的os.walk()函数遍历目录,逐一删除
- 需要导入os模块
- 能够删除指定目录下的文件和子目录,但是不会删除指定的目录
import os
for root, dirs, files in os.walk("python/test", topdown=False):
for name in files:
os.remove(os.path.join(root, name))
for name in dirs:
os.rmdir(os.path.join(root, name))
4. 文件检查
1) 判断文件是否存在
判断文件是否存在
推荐写法: 使用Python3的标准库,os模块的os.path.exists()函数
- 需要导入os模块
- 可以检查文件或者目录是否存在
import os
# 文件存在时
os.path.exists("doc/resource/file/check/file_exists") # 结果:True
# 文件不存在时
os.path.exists("doc/resource/file/check/file_not_exists") # 结果:False
# 当存在和文件同名的目录时,可能命中同名目录,影响判断结果
# 此时可以在文件名上加后缀区分,或者使用os.path.isdir()/os.path.isfile()加以区分
filename = "doc/resource/file/check/file_exists"
os.path.exists("doc/resource/file/check/file_exists.py") # 结果:True
os.path.isfile(filename) & os.path.exists(filename) # 结果:True
not os.path.isdir(filename) & os.path.exists(filename) # 结果:True
推荐写法: 使用Python3的标准库,内置函数exists()
- 需要导入pathlib模块
- 可以检查文件或者目录是否存在
from pathlib import Path
# 文件存在时
path = Path("doc/resource/file/check/file_exists")
path.exists() # 结果:True
# 文件不存在时
path = Path("doc/resource/file/check/file_not_exists")
path.exists() # 结果:False
# 当存在和文件同名的目录时,可能命中同名目录,影响判断结果
# 此时可以在文件名上加后缀区分,或者使用os.path.isdir()/os.path.isfile()加以区分
path = Path("doc/resource/file/check/file_exists")
path.exists() & path.is_file() # 结果:True
not path.is_dir() & path.exists() # 结果:True
path1 = Path("doc/resource/file/check/file_exists.py")
path1.exists() # 结果:True
2) 判断文件内容是否相等
判断两个文件的内容是否相等
推荐写法: 使用Python3的标准库,filecmp模块的filecmp.cmp()函数
- 需要导入filecmp模块
- filecmp.cmp(f1,f2[,shallow]),可选参数shallow指定比较文件时是否需要考虑文件本身的属性,默认为True
- 当传入的文件内容相等时返回True,不等时返回False
- 当传入的文件不存在时,引发异常:FileNotFoundError
import filecmp
file1 = "file_exist"
file2 = "file_exist_copy"
filecmp.cmp(file1, file2) # 结果:True
file3 = "file_not_exist"
filecmp.cmp(file1, file3) # 引发异常:FileNotFoundError
推荐写法: 使用Python3的标准库,filecmp模块的filecmp.cmpfiles()函数
- 需要导入filecmp模块
- filecmp.cmpfiles(dir1,dir2,common[,shallow]),可选参数shallow指定比较文件时是否需要考虑文件本身的属性,默认为True
- 比较两个文件夹内指定文件(同名文件比较)是否相等,返回包含三个list的元组,分别表示匹配、不匹配以及错误的文件列表,错误的文件是指不存在的、被锁定不可读、无权限读取等无法访问的文件
import filecmp
dir1 = "/pythonTest/work"
dir2 = "/pythonTest/test"
# 两个文件夹内都存在test.py,且内容相同
filecmp.cmp(dir1, dir2, ["test.py"]) # 结果:True
5. 文件移动
1) 移动文件
移动文件
推荐写法: 使用Python3的标准库,shutil模块的shutil.move()函数
- 需要导入shutil模块
- 移动文件到指定的目录,当移动的文件不存在、指定目录不存在或指定目录中存在同名文件时,引发异常
import shutil
srcname = "python/src_dir/file_exist"
destname = "python/des_dir"
# 当源文件和指定目录都存在时,移动成功
shutil.move(srcname, destname)
# 当源文件存在,但是指定目录不存在时,将会把文件重命名为指定目录名称
destname1 = "python/des_dir_not_exist"
shutil.move(srcname, destname1)
# 当指定目录存在,但指定目录中已经存在同名文件时,即使源文件不存在同样会引发异常
# shutil.Error: Destination path'python/des_dir/file_exist' already exists
shutil.move(srcname, destname)
# 当源文件不存在时,引发异常
# FileNotFoundError: [Errno 2] No such file or directory: 'python/src_dir/file_exist'
shutil.move(srcname, destname)
2) 移动目录
移动目录
推荐写法: 使用Python3的标准库,shutil模块的shutil.move()函数
- 需要导入shutil模块
- 移动目录及其所有文件、子文件夹到指定的目录
import shutil
srcname = "python/src_dir"
destname = "python/des_dir"
# 当源目录和指定目录都存在时,移动成功
shutil.move(srcname, destname)
# 当源目录存在,但是指定目录不存在时,将会创建指定目录,并把源目录的内容移动到指定目录
destname1 = "python/des_dir_not_exist"
shutil.move(srcname, destname1)
# 当源目录和指定目录都存在,但指定目录中已经存在同名对象时,引发异常
# shutil.Error: Destination path 'python/des_dir/src_dir' already exists
shutil.move(srcname, destname)
# 当源目录不存在时,引发异常
# FileNotFoundError: [Errno 2] No such file or directory: 'python/src_dir'
shutil.move(srcname, destname)
6. 文件复制
1) 拷贝文件
拷贝文件
推荐写法: 使用Python3的标准库,shutil模块的copyfile()函数
- 需要导入shutil模块
- 源和目标都只能是文件
- 如果目标不可写,复制操作将引发异常
- 如果目标文件已存在且可写时,覆盖其内容
- copyfile()调用了copyfileobj()复制内容
import shutil
src_file = "python/test_exist.py"
dst_file = "python/test_copy_not_exist.py"
# 源和目标都是文件,且源对象存在,复制成功
shutil.copyfile(src_file, dst_file)
# 源或者目标不是文件对象时,引发异常
# PermissionError: [Errno 13] Permission denied
dst_file1 = "python/iamdir"
shutil.copyfile(src_file, dst_file1)
# 源文件存在,目标文件已存在但不可写时,引发异常
# PermissionError: [Errno 13] Permission denied
dst_file2 = "python/test1.py"
shutil.copyfile(src_file, dst_file2)
# 如果源和目标都相同,引发异常
# shutil.SameFileError
dst_file3 = "python/test_exist.py"
shutil.copyfile(src_file, dst_file3)
# 当源文件不存在时,引发异常
# FileNotFoundError: [Errno 2] No such file or directory
src_file1 = "python/test_not_exist.py"
shutil.copyfile(src_file1, dst_file)
推荐写法: 使用Python3的标准库,shutil模块的shutil.copy()函数
- 需要导入shutil模块
- 源只能是文件,目标可以是文件,也可以是目录
- 如果当前路径中已存在同名称文件且可写,则直接覆盖掉
- copy()依次调用了copyfile()和copymode()复制内容的同时复制权限
import shutil
src_file = "python/test_exist.py"
dst_file = "python/test_copy_not_exist.py"
# 复制成功
# 如果目标是目录,且不存在,则copy方法会认为目标是一个文本文件,并复制内容
shutil.copy(src_file, dst_file)
# 源不是文件对象时,引发异常
# PermissionError: [Errno 13] Permission denied
src_file1 = "python/iamdir"
shutil.copy(src_file1, dst_file)
# 源文件存在,目标文件已存在但不可写时,引发异常
# PermissionError: [Errno 13] Permission denied
dst_file2 = "python/test1.py"
shutil.copy(src_file, dst_file2)
# 如果源和目标都相同,引发异常
# shutil.SameFileError
dst_file3 = "python/test_exist.py"
shutil.copy(src_file, dst_file3)
# 当源文件不存在时,引发异常
# FileNotFoundError: [Errno 2] No such file or directory
src_file2 = "python/test_not_exist.py"
shutil.copy(src_file2, dst_file)
推荐写法: 使用Python3的标准库,shutil模块的copy2()函数
- 需要导入shutil模块
- copy2()函数和copy()类似,但是调用了copystat()而不是copymode(),因此,复制数据的同时,会复制源文件的访问和修改时间
import shutil
src_file = "python/test_exist.py"
dst_file = "python/test_copy_not_exist.py"
# 复制成功
# 如果目标是目录,且不存在,则copy方法会认为目标是一个文本文件,并复制内容
shutil.copy2(src_file, dst_file)
# 源不是文件对象时,引发异常
# PermissionError: [Errno 13] Permission denied
src_file1 = "python/iamdir"
shutil.copy2(src_file1, dst_file)
# 源文件存在,目标文件已存在但不可写时,引发异常
# PermissionError: [Errno 13] Permission denied
dst_file2 = "python/test1.py"
shutil.copy2(src_file, dst_file2)
# 如果源和目标都相同,引发异常
# shutil.SameFileError
dst_file3 = "python/test_exist.py"
shutil.copy2(src_file, dst_file3)
# 当源文件不存在时,引发异常
# FileNotFoundError: [Errno 2] No such file or directory
src_file2 = "python/test_not_exist.py"
shutil.copy2(src_file2, dst_file)
一般写法: 使用Python3的标准库,shutil模块的shutil.copyfileobj(fsrc, fdst, length=16*1024)函数
- 需要导入shutil模块
- 参数是两个文件的指针open(file_path,mode),其中源文件的mode为r,目标文件的mode为w或a
- 复制源文件的内容
- 如果当前路径中已存在同名称文件且可写,则直接覆盖掉
- 可选参数length可以设置缓冲区长度
- 因为使用了open()函数,因此拷贝完成后最好显式地关闭资源
import shutil
src_file = open("python/src_file_exist.py", "r")
dst_file = open("python/dst_file_not_exist", "w")
try:
shutil.copyfileobj(src_file, dst_file)
finally:
src_file.close()
dst_file.close()
# 当源文件不存在时,引发异常
# FileNotFoundError: [Errno 2] No such file or directory
src_file1 = open("python/test_not_exist.py", 'r')
try:
shutil.copyfileobj(src_file, dst_file)
finally:
src_file1.close()
dst_file.close()
# 如果源和目标都相同,清空源文件内容
dst_file1 = open("python/src_file_exist.py", "w")
try:
shutil.copyfileobj(src_file, dst_file1)
finally:
src_file.close()
dst_file1.close()
# 源文件存在,目标文件已存在但不可写时,引发异常
# PermissionError: [Errno 13] Permission denied
dst_file2 = open("python/test1.py", "w")
try:
shutil.copyfileobj(src_file, dst_file2)
finally:
src_file.close()
dst_file2.close()
# 源不是文件对象时,引发异常
# PermissionError: [Errno 13] Permission denied
src_file2 = open("python/iamdir", "r")
try:
shutil.copyfileobj(src_file2, dst_file)
finally:
src_file2.close()
dst_file.close()
2) 文件拷贝到指定目录
拷贝文件到指定目录
推荐写法: 使用Python3的标准库,shutil模块的shutil.copy()函数
- 需要导入shutil模块
- 源只能是文件,目标可以是文件,也可以是目录
- 如果当前路径中已存在同名称文件且可写,则直接覆盖掉
- copy()依次调用了copyfile()和copymode()复制内容的同时复制权限 推荐
import shutil
src_file = "python/test_exist.py"
dst_dir = "python/test"
# 复制成功
# 如果目标目录不存在,则copy方法会认为目标是一个文本文件,并复制内容
shutil.copy(src_file, dst_dir)
# 源不是文件对象时,引发异常
# PermissionError: [Errno 13] Permission denied
src_file1 = "python/iamdir"
shutil.copy(src_file1, dst_dir)
# 当源文件不存在时,引发异常
# FileNotFoundError: [Errno 2] No such file or directory
src_file2 = "python/test_not_exist.py"
shutil.copy(src_file2, dst_dir)
推荐写法: 使用Python3的标准库,shutil模块的copy2()函数
- 需要导入shutil模块
- copy2()函数和copy()类似,但是调用了copystat()而不是copymode(),因此,复制数据的同时,会复制源文件的访问和修改时间
import shutil
src_file = "python/test_exist.py"
dst_dir = "python/test"
# 复制成功
# 如果目标是目录,且不存在,则copy方法会认为目标是一个文本文件,并复制内容
shutil.copy2(src_file, dst_dir)
# 源不是文件对象时,引发异常
# PermissionError: [Errno 13] Permission denied
src_file1 = "python/iamdir"
shutil.copy2(src_file1, dst_dir)
# 当源文件不存在时,引发异常
# FileNotFoundError: [Errno 2] No such file or directory
src_file2 = "python/test_not_exist.py"
shutil.copy2(src_file2, dst_dir)
3) 文件目录拷贝
将文件目录及其子目录拷贝到某个目录下
推荐写法: 使用Python3的标准库,shutil模块的shutil.copytree()函数
- 需要导入shutil模块
- 源和目标都必须是目录,且目标目录必须不存在
import shutil
src_dir = "python/src_dir_exist"
dst_dir = "python/dst_dir_not_exist"
# 当源目录存在,目标目录不存在时,复制成功
shutil.copytree(src_dir, dst_dir)
# 当源目录存在,目标目录已存在时,引发异常
# FileExistsError: [WinError 183] 当文件已存在时,无法创建该文件。
dst_dir1 = "python/dst_dir_exist"
shutil.copytree(src_dir, dst_dir1)
# 当源目录不存在时,引发异常
# FileNotFoundError: [WinError 3] 系统找不到指定的路径
src_dir1 = "python/src_dir_not_exist"
shutil.copytree(src_dir1, dst_dir)
# 当源不是一个目录对象时,引发异常
# NotADirectoryError: [WinError 267] 目录名称无效。
src_dir2 = "python/src.py"
shutil.copytree(src_dir2, dst_dir)
7. 文件读写
Python区分文本和二进制I/O:
- 文本模式只能读普通文本文件;二进制模式不仅可以读文本文件,还可以读二进制文件(如图片、声音文件);
- Python对文件读取采用统一的操作步骤:打开–读取–关闭。
- 本章节假定在parent_path路径下已有如下三个文件:
- 编码格式为UTF-8的文本文件:read_file_utf-8,文件内容如下:
hello world!
This is a UTF-8 text file.
hello python! - 编码格式为GBK的文本文件:read_file_gbk,文件内容如下:
你好,世界!
这是一个GBK编码的文本文件。
你好,python! - 图片文件:read_img.PNG
1) 以文本模式读文件
推荐写法: 使用Python3的标准库,内置函数:open(file[, mode=‘r’, encoding=None])
- file用于指定文件路径,若文件不存在,会抛出FileNotFoundError
- 使用“t”模式即文本模式,设置mode="r"或"rt"或省略,表示以只读方式在文本模式下打开文件
- encoding是可选参数,用于指定文件编码(只用于文本模式),对于非UTF-8编码格式的文本文件,需要设 置encoding=“xxx”
- 使用with语句,可以自动调用close()方法关闭文件流
# 读UTF-8编码的文本文件
with open(r"parent_path\read_file_utf-8") as f:
for line in f:
"""process line"""
# 读GBK编码的文本文件
with open(r"parent_path\read_file_gbk", encoding="GBK") as f:
for line in f:
"""process line"""
2) 以二进制模式读文件
推荐写法: 使用Python3的标准库,内置函数:open(file, mode=‘rb’)
- file用于指定文件路径,若文件不存在,会抛出FileNotFoundError
- 使用“b”模式即二进制模式,设置mode=“rb”,表示以只读方式在二进制模式下打开文件
- 使用with语句,可以自动调用close()方法关闭文件流
# 读图片文件
with open(r"parent_path\read_img.PNG", "rb") as f:
for line in f:
"""process line"""
3) 读取文件全部内容(文本文件、二进制文件)
注意:对于大文件,一次性读取文件全部内容并不是明智的,存在撑爆内存的风险
推荐写法: 使用Python3的标准库,IO类内置函数:read()
- 从流中读取文件全部内容并返回
# 读UTF-8编码的文本文件
with open(r"parent_path\read_file_utf-8") as f:
print(f.read())
'''
hello world!
This is a UTF-8 text file.
hello python!
'''
# 以二进制模式读文件
with open(r"parent_path\read_img.PNG", mode="rb") as f:
# b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x0e\x00\x00"
print(f.read())
推荐写法: 使用Python3的标准库,IO类内置函数:readlines()
- 从流中读取文件全部内容,返回一个list,其中每一行作为list的一个元素
- 本质是循环调用函数readline(),并返回读取的行列表
# 读gbk编码的文本文件
with open(r"parent_path\read_file_gbk", encoding="GBK") as f:
print(f.readlines())
# ['你好,世界!\n', '这是一个GBK编码的文本文件。\n', '你好,python!']
# 以二进制模式读文件
with open(r"parent_path\read_img.PNG", mode="rb") as f:
# [b'\x89PNG\r\n', b'\x1a\n', b"\x00\x00\x00\rIHDR\x00\x00\x00\x0e\x00\x00"]
print(f.readlines())
4) 读取一行内容(文本文件、二进制文件)
推荐写法: 使用Python3的标准库,IO类内置函数:readline()
- 从流中读取一行内容并返回
# 以文本模式读文件
with open(r"parent_path\read_file_utf-8") as f:
print(f.readline())
'''
hello world!
'''
# 以二进制模式读文件
with open(r"parent_path\read_img.PNG", mode="rb") as f:
print(f.readline()) # b'\x89PNG\r\n'
5) 读取指定size的内容(文本文件、二进制文件)
推荐写法: 使用Python3的标准库,IO类内置函数:read(size)
- size用于指定读取的字节数,读取的内容最多不超过size大小
- 若size<0,则返回文件全部内容;若size=0,则返回空
- 若size>0,则返回size大小的内容(若size超过文件容量则返回文件全部内容) 推荐
# 以文本模式读文件
with open(r"parent_path\read_file_gbk", encoding="GBK") as f:
print(f.read(8))
'''
你好,世界!
这
'''
# 以二进制模式读文件
with open(r"parent_path\read_img.PNG", mode="rb") as f:
print(f.read(8)) # b'\x89PNG\r\n\x1a\n'
推荐写法: 使用Python3的标准库,IO类内置函数:readlines(size)
- 返回一个list,其中每一行作为list的一个元素,读取的内容最多不超过size大小
- 本质是循环调用函数readline(),并返回读取的行列表
# 以文本模式读文件
with open(r"parent_path\read_file_utf-8") as f:
print(f.readlines(15)) # ['hello world!\n', 'This is a UTF-8 text file.\n']
# 以二进制模式读文件
with open(r"parent_path\read_img.PNG", mode="rb") as f:
print(f.readlines(6)) # [b'\x89PNG\r\n', b'\x1a\n']
6) 读取指定位置的内容(文本文件、二进制文件)
推荐写法: 使用Python3的标准库,IO类内置函数:seek(offset[, whence])
- 用于改变文件指针的位置
- offset用于指定偏移量,whence是可选参数,用于指定偏移量的相对位置,值只能是0,1,2
- 若whence=0(默认),表示相对于文件开始位置偏移,则应该设置offset>=0
- 若whence=1,表示相对于当前位置偏移,则offset正负均可
- 若whence=2,表示相对于文件结束位置偏移,则应该设置offset<0
- 若使用“t”模式选项打开文件,则只允许从文件开始位置偏移,否则会抛出UnsupportedOperation
- 若使用“b”模式选项打开文件,则上述三种情况均可
- 使用IO类内置函数tell()可以获取文件指针的位置,返回一个整数
# 以文本模式读文件
with open(r"parent_path\read_file_utf-8") as f:
f.seek(4, 0)
print(f.tell()) # 4
print(f.read(8)) # o world!
# 以二进制模式读文件
with open(r"parent_path\read_file_utf-8", mode="rb") as f:
f.seek(4, 0)
print(f.tell()) # 4
print(f.read(8)) # b'o world!'
f.seek(4, 1)
print(f.tell()) # 16
print(f.read(8)) # b'is is a
print(f.tell()) # 24
f.seek(-16, 1)
print(f.tell()) # 8
print(f.read(8)) # b'rld!\r\nTh'
print(f.tell()) # 16
f.seek(-8, 2)
print(f.tell()) # 47
print(f.read()) # b' python!'
7) 以文本模式写文件
**推荐写法: 使用Python3的标准库,内置函数:open(file, mode=‘w’[, encoding=None])和IO类内置函数:write(str) **
- file用于指定文件路径,若文件不存在,则创建该文件(默认是UTF-8编码)
- 使用“t”模式即文本模式,设置mode="w"或"wt"或省略,表示以只写方式在文本模式下打开文件
- 若mode=“w”,若文件已存在,则会清除并覆盖掉其内容
- 若mode=“a”,若文件已存在,则新的内容会被追加到已有内容之后
- 对于非UTF-8编码格式的文本文件,需要设置encoding=“xxx”
- 使用with语句,可以自动调用close()方法关闭文件流
- write(str)函数用于写入一个字符串
# 创建UTF-8编码文件write_file,写入"hello world!"
with open(r"parent_path\write_file", mode="w") as f:
f.write("hello world!")
# 文件内容存在,将其覆盖掉,写入"hello world again."
with open(r"parent_path\write_file", mode="w") as f:
f.write("hello world again.")
# 文件内容存在,追加"\nhello python!"
with open(r"parent_path\write_file", mode="a") as f:
f.write("\nhello python!")
# 创建GBK编码文件write_file_gbk,写入"你好,世界!"
with open(r"parent_path\write_file_gbk", mode="w", encoding="GBK") as f:
f.write("你好,世界!")
8) 以二进制模式写文件
推荐写法: 使用Python3的标准库,内置函数:open(file, mode=‘wb’)
- 使用“b”模式即二进制模式,设置mode=“wb”,用法同上
# 创建UTF-8编码文件write_file,写入"hello world!"
with open(r"parent_path\write_file_byte", mode="wb") as f:
f.write(b'abc')
9) 写入一个字符串
推荐写法: 使用Python3的标准库,IO类内置函数:write(str)
- 用于写入一个字符串
# 创建UTF-8编码文件write_file,写入"hello world!"
with open(r"parent_path\write_file", mode="wt", encoding="UTF-8") as f:
f.write("hello world!")
10) 写入多个字符串
推荐写法: 使用Python3的标准库,IO类内置函数:writelines(lines)
- lines用于接收一个字符串列表或一个字符串
- 若lines是字符串列表,可用于写入多个字符串,不会自动换行,如果需要,必须自己制定换行符,
- 若列表中字符串的末尾都没有换行符,则相当于写入了一行数据 若lines是字符串,则用法同write(str),可写入一个字符串
# 写入一个字符串
with open(r"parent_path\write_lines", mode="wt", encoding="UTF-8") as f:
f.writelines("hello world!")
# 以追加模式写入多行字符串
with open(r"parent_path\write_lines", mode="at", encoding="UTF-8") as f:
f.writelines(["hello,python!\n", "hello,IO!"])
8. 路径判断
1) 判断是否为目录
推荐写法: 使用Python3的标准库,os模块的os.path.isdir()函数
- 需要导入os模块
import os
path = Path('/CODE/pythonCodeGuide/PythonCodingGuide')
if os.path.isdir(path): # 返回True
'''路径是一个目录'''
path = Path('pythonCodeGuide/PythonCodingGuide')
# 路径不存在时,返回False
if os.path.isdir(path):
'''路径不存在'''
path = Path('/CODE/pythonCodeGuide/PythonCodingGuide/main.py')
# 路径不是目录时,返回False
if os.path.isdir(path):
'''路径不是一个目录'''
推荐写法: 使用Python3的标准库,内置函数is_dir()
path = Path('/CODE/pythonCodeGuide/PythonCodingGuide')
if path.is_dir(): # 返回True
'''路径是一个目录'''
path = Path('pythonCodeGuide/PythonCodingGuide')
# 路径不存在时,返回False
if path.is_dir():
'''路径不存在'''
path = Path('/CODE/pythonCodeGuide/PythonCodingGuide/main.py')
# 路径不是目录时,返回False
if path.is_dir():
'''路径不是一个目录'''
2) 判断是否为文件
推荐写法: 使用Python3的标准库,os模块的os.path.isfile()函数
- 需要导入os模块
import os
path = Path('/CODE/pythonCodeGuide/PythonCodingGuide/main.py')
if os.path.isfile(path): # 返回True
'''路径是一个文件'''
path = Path('pythonCodeGuide/PythonCodingGuide')
# 路径不存在时,返回False
if os.path.isfile(path):
'''路径不存在'''
path = Path('/CODE/pythonCodeGuide/PythonCodingGuide')
# 路径不是文件时,返回False
if os.path.isfile(path):
'''路径不是一个文件'''
推荐写法: 使用Python3的标准库,内置函数is_file()
path = Path('/CODE/pythonCodeGuide/PythonCodingGuide/main.py')
if path.is_file(): # 返回True
'''路径是一个文件'''
path = Path('pythonCodeGuide/test')
# 路径不存在时,返回False
if path.is_file():
'''路径不存在'''
path = Path('/CODE/pythonCodeGuide/PythonCodingGuide')
# 路径不是文件时,返回False
if path.is_file():
'''路径不是一个文件'''
3) 判断path是否存在
推荐写法: 使用Python3的标准库,os模块的os.path.exists()函数
- 需要导入os模块
import os
path = Path('/CODE/pythonCodeGuide/PythonCodingGuide')
# 路径存在,返回True
if os.path.exists(path):
'''路径存在'''
path = Path('/pythonCodeGuide/PythonCodingGuide')
# 路径不存在,返回False
if os.path.exists(path):
'''路径不存在'''
推荐写法: 使用Python3的标准库,内置函数exists()
path = Path('/CODE/pythonCodeGuide/PythonCodingGuide')
# 路径存在,返回True
if path.exists():
'''路径存在'''
path = Path('/pythonCodeGuide/PythonCodingGuide')
# 路径不存在,返回False
if path.exists():
'''路径不存在'''
4) 判断是否为绝对路径
推荐写法: 使用Python3的标准库,os模块的os.path.isabs()函数
- 需要导入os模块
- 即使目标路径是不存在的,只要命名对象是绝对路径,就返回True
import os
path = Path("D:/pythonCodeGuide/test")
# 当是绝对路径时,返回True
if os.path.isabs(path):
'''是绝对路径'''
path = Path("/pythonCodeGuide/test")
# 当不是绝对路径时,返回False
if os.path.isabs(path):
'''不是绝对路径'''
推荐写法: 使用Python3的标准库,内置函数is_absolute()
- 即使目标路径是不存在的,只要命名对象是绝对路径,就返回True
path = Path("D:/pythonCodeGuide/test")
# 当是绝对路径时,返回True
if path.is_absolute():
'''是绝对路径'''
path = Path("/pythonCodeGuide/test")
# 当不是绝对路径时,返回False
if path.is_absolute():
'''不是绝对路径'''
5) 判断是否为符号链接
推荐写法: 使用Python3的标准库,os模块的os.path.islink()
- 如果文件不存在,os.path.islink()返回False
import os
# iamfile-s -> /CODE/pythonCodeGuide/PythonCodingGuide/doc/resource/iamfile
path = Path("/CODE/pythonCodeGuide/PythonCodingGuide/iamfile-s")
# 当对象是一个符号链接时,返回True
if os.path.islink(path):
'''是一个符号链接'''
path = Path("/CODE/pythonCodeGuide/PythonCodingGuide/doc/resource/iamfile")
# 当对象不是一个符号链接时,返回False
if os.path.islink(path):
'''不是一个符号链接'''
推荐写法: 使用Python3的标准库,内置函数is_symlink()
- 如果文件不存在,os.path.islink()返回False
# iamfile-s -> /CODE/pythonCodeGuide/PythonCodingGuide/doc/resource/iamfile
path = Path("/CODE/pythonCodeGuide/PythonCodingGuide/iamfile-s")
# 当对象是一个符号链接时,返回True
if path.is_symlink():
'''是一个符号链接'''
path = Path("/CODE/pythonCodeGuide/PythonCodingGuide/doc/resource/iamfile")
# 当对象不是一个符号链接时,返回False
if path.is_symlink():
'''不是一个符号链接'''
6) 判断是否为目录的符号链接
推荐写法: 使用Python3的标准库,判断是否为目录的符号链接
def is_dir_symlink(location):
"""第一步:转换为path
第二步:path为符号链接文件
第三步:判断符号链接的目标文件是否是目录"""
path = Path(location)
if not path.exists():
return False
return path.is_symlink() & path.is_dir()
# 或者引入os模块 return os_path_islink() & os.path.isdir()
# iamdir-s -> /CODE/pythonCodeGuide/PythonCodingGuide/doc/resource/iamdir
# 对象为符号链接,且为目录的符号链接
is_dir_symlink("/CODE/pythonCodeGuide/PythonCodingGuide/iamdir-s") # 结果:True
# 对象不是符号链接
is_dir_symlink("/CODE/pythonCodeGuide/PythonCodingGuide/iamdir-h") # 结果:False
# 对象不存在
is_dir_symlink("/CODE/pythonCodeGuide/PythonCodingGuide/iamdir_not_exist") # 结果:False
7) 判断是否为文件的符号链接
推荐写法: 使用Python3的标准库,判断是否为文件的符号链接
def is_file_symlink(location):
"""第一步:转换为path
第二步:path为符号链接文件
第三步:判断符号链接的目标文件是否是文件"""
path = Path(location)
if not path.exists():
return False
return path.is_symlink() & path.is_file()
# 或者引入os模块 return os_path_islink() & os.path.isfile()
# iamfile-s -> /CODE/pythonCodeGuide/PythonCodingGuide/doc/resource/iamfile
# 对象为符号链接,且为文件的符号链接
is_file_symlink("/CODE/pythonCodeGuide/PythonCodingGuide/iamfile-s") # 结果:True
# 对象为普通文件
is_file_symlink("/CODE/pythonCodeGuide/PythonCodingGuide/iamfile-h") # 结果:False
# 对象文件不存在
is_file_symlink("/CODE/pythonCodeGuide/PythonCodingGuide/iamfile_not_exist") # 结果:False
8. 目录创建
1) 创建单个目录
推荐写法: 使用Python3的标准库,os模块的函数:os.mkdir(path[, mode=0o777])
- 需要导入os模块
- 用于在已存在的目录中创建一个文件夹,path指代一个文件夹名或路径,mode为权限模式(因平台而异)
- 若path是文件夹名,则默认在当前目录下创建
- 若path包含路径,则必须给出一个已存在的父路径,否则会抛出FileNotFoundError
- 若路径中包含转义字符,可使用双斜线“\”或“r”前缀,消除转义字符
- 若目标文件夹已存在,会抛出FileExistsError
import os
os.mkdir("dir1") # 在当前目录下创建dir
# 抛出FileExistsError: [WinError 183] 当文件已存在时,无法创建该文件。: 'dir1'
os.mkdir("dir1")
# 抛出FileNotFoundError: [WinError 3] 系统找不到指定的路径。: '\\test\\dir1'
os.mkdir("\\test\\dir1")
# 在parent_path下创建dir2
os.mkdir(r"parent_path\dir2")
2) 创建多级目录
推荐写法: 使用Python3的标准库,os模块的函数:os.makedirs(name [, mode=0o777, exist_ok=False])
- 需要导入os模块
- 用于递归创建一个或多个文件夹,name指代一个文件夹名或路径,mode为权限模式
- 若name是文件夹名,则默认在当前目录下创建
- 若name包含路径,则会递归创建所有给出的不存在的文件夹
- 若目标文件夹已存在:exists_ok=False(默认),抛出FileExistsError;exists_ok=True,不会抛出异常
import os
os.makedirs("dir1") # 在当前目录下创建dir
# 抛出FileExistsError: [WinError 183] 当文件已存在时,无法创建该文件。: 'dir1'
os.makedirs("dir1")
os.makedirs("dir1", exist_ok=True) # 设置exist_ok=True,当目标文件夹已存在,不会抛出异常
os.makedirs("test\\dir2") # 在当前目录下创建test,在test下创建dir2
os.makedirs(r"parent_path\dir3") # 创建"parent_path\\dir3"路径上所有不存在的文件夹
9. 目录操作
1) 目录遍历
推荐写法: 使用Python3的标准库,os模块的函数:os.walk(top[, topdown=True, οnerrοr=None,followlinks=False])
- 需要导入os模块
- 递归遍历指定路径,返回一个(dirpath, dirnames, filenames)三元组
- dirpath是一个字符串,表示目录的路径;dirnames是一个列表,包含了dirpath下所有的一级目录的名字(不包含子目录);filenames是一个列表,包含了dirpath下所有的文件的名字(不包含子目录),使用函数os.path.join(dirpath, name)可得到文件的全路径
- top指定要遍历的目录的路径,其它三个是可选参数,topdown指定递归遍历的顺序,onerror指定异常时的回调函数
- 若topdown=True(默认),则自顶向下深度遍历目录树,先遍历父目录,再遍历子目录
- 若topdown=False,则自底向上遍历目录树,先遍历子目录,再遍历父目录
import os
# 自顶向下遍历目录树
for dirpath, dirnames, filenames in os.walk("parent_path\\path"):
print(dirpath) # 返回一个string,表示目录的路径
print(dirnames) # 返回一个list,包含了dirpath下所有的一级目录名
print(filenames) # 返回一个list,包含了dirpath下所有的文件名
for name in filenames:
print(os.path.join(dirpath, name)) # 获取top目录下所有文件的全路径(包括子目录)
2) 列举目录下所有文件(不包含子文件夹)
获取文件夹下的所有文件(不包含子文件夹)
推荐写法: 使用Python3的标准库,os模块的os.listdir()函数
- 需要导入os模块
- os.listdir()函数会列出目标目录下所有文件以及子目录名称
- 使用os.path.isfile()函数筛选出其中的文件
import os
file_list = [f for f in os.listdir("/pythonTest/work") if os.path.isfile(os.path.join("/pythonTest/work", f))]
# 也可以写成如下形式
for filename in os.listdir("/pythonTest/work"):
if os.path.isfile(filename):
print(filename)
推荐写法: 使用Python3的标准库,os模块的os.walk()函数
- 需要导入os模块
- 递归遍历指定路径,返回一个(dirpath, dirnames, filenames)三元组,如果只需要顶层目录下的文件,只需要在第一次迭代后break即可
import os
file_list = []
for (dirpath, dirnames, filenames) in os.walk("/pythonTest/work"):
file_list.extend(filenames)
break
3) 列举目录下所有文件(包含子文件夹)
获取文件夹下的所有文件(包含子文件夹)
推荐写法: 使用Python3的标准库,os模块的os.walk()函数
- 需要导入os模块
- 递归遍历指定路径,返回一个(dirpath, dirnames, filenames)三元组,如果只需要文件名,取出filenames即可
import os
file_list = []
for (dirpath, dirnames, filenames) in os.walk("/pythonTest/work"):
file_list.extend(filenames)
一般写法: 使用Python3的标准库,os模块的os.listdir()函数
- 需要导入os模块
import os
def print_files(path):
"""第一步:os.listdir()函数列出目标目录下所有的文件和子目录;
第二步:dirs返回当前目录下的所有目录,递归dirs直到最深一层;
第三步:打印所有文件名"""
lsdir = os.listdir(path)
dirs = [i for i in lsdir if os.path.isdir(os.path.join(path, i))]
if dirs:
for i in dirs:
print_files(os.path.join(path, i))
files = [i for i in lsdir if os.path.isfile(os.path.join(path, i))]
for f in files:
print(f)
print_files("/pythonTest/work")
4) 列举当前目录下符合条件的文件
获取当前目录下符合条件的文件名
推荐写法: 使用Python3的标准库,glob模块的glob.glob()函数
- 需要导入glob模块
- 返回目录下符合条件的文件名的列表
- 不包含子目录下的文件
import glob
# 获取顶层目录下所有python文件名
glob.glob("/pythonTest/work/*.py")
推荐写法: 使用Python3的标准库,os模块的os.walk()函数
- 需要导入os模块
- 获取所有文件后筛选出符合条件的文件
- 若需要包含子目录下的文件,去掉break即可
import os
# 筛选出顶层目录下的python文件
file_list = []
for (dirpath, dirnames, filenames) in os.walk("/pythonTest/work"):
for item in filenames:
if ".py" in item:
file_list.append(item)
break
print(file_list)
5) 列举目录下所有子目录
获取文件夹下的所有子目录
推荐写法: 使用Python3的标准库,os模块的os.listdir()函数
- 需要导入os模块
- os.listdir()函数会列出目标目录下所有文件以及子目录名称
- 使用os.path.isdir()函数筛选出其中的目录
import os
"""只包含顶层目录下的子目录"""
dir_list = [f for f in os.listdir("/pythonTest/work") if os.path.isdir(os.path.join("/pythonTest/work", f))]
# 也可以写成如下形式
for filename in os.listdir("/pythonTest/work"):
if os.path.isdir(filename):
print(filename)
"""获取目录下的所有子目录名称"""
def print_files(path):
lsdir = os.listdir(path)
dirs = [i for i in lsdir if os.path.isdir(os.path.join(path, i))]
if dirs:
for i in dirs:
print_files(os.path.join(path, i))
sub_dirs = [i for i in lsdir if os.path.isdir(os.path.join(path, i))]
for f in sub_dirs:
print(f)
print_files("/pythonTest/work")
推荐写法: 使用Python3的标准库,os模块的os.walk()函数
- 需要导入os模块
- 递归遍历指定路径,返回一个(dirpath, dirnames,filenames)三元组,如果只需要顶层目录下的目录,只需要在第一次迭代后break即可
import os
"""只包含顶层目录下的子目录"""
dir_list = []
for (dirpath, dirnames, filenames) in os.walk("/pythonTest/work"):
dir_list.extend(dirnames)
break
"""获取目录下的所有子目录名称"""
dir_list = []
for (dirpath, dirnames, filenames) in os.walk("/pythonTest/work"):
dir_list.extend(dirnames)