0
点赞
收藏
分享

微信扫一扫

Python中的高级文件操作模块shutil


高级文件操作模块shutil

目录结构

  • ​​高级文件操作模块shutil​​
  • ​​常用方法​​
  • ​​copy拷贝方法​​
  • ​​rm删除方法​​
  • ​​move移动方法​​

常用方法

copy拷贝方法
  • copyfileobj(fsrc,fdst[,length]) #拷贝文件对象,将fsrc文件对象内容拷贝到fdst文件对象中。复制文件内容,不含元数据
  • fsrc:源文件对象,是open打开的文件对象
  • fdst: 目标文件对象,是open打开的文件对象
  • length:缓冲区buffer的大小,可选参数,默认是16*1024
  • 注意:如果源文件是文本模式打开,目标文件一定也要是文本模式写入
  • python对应原码如下:

def copyfileobj(fsrc, fdst, length=16*1024):
"""copy data from file-like object fsrc to file-like object fdst"""
while 1:
buf = fsrc.read(length)
if not buf:
break
fdst.write(buf)

  • coypfile(src,dst,*,follow_symlinks=True) #根据文件路径,拷贝文件。复制文件内容,不含元数据。本质上是用copyfileobj对象拷贝
  • src:源文件路径,可以是Path对象或者字符串文件路径对象
  • dst:目标文件路径,可以是Path对象或者字符串文件路径对象
  • follow_symlinks = True,是否跟进链接文件。
  • True:表示拷贝链接文件所指向的文件
  • False:表示拷贝链接文件本身
  • Python中部分源码如下:

def copyfile(src, dst, *, follow_symlinks=True):
##部分代码以省略##
if not follow_symlinks and os.path.islink(src):
os.symlink(os.readlink(src), dst)
else:
with open(src, 'rb') as fsrc:
with open(dst, 'wb') as fdst:
copyfileobj(fsrc, fdst)
return

  • copymode(src,dst,*,follow_symlinks=True) #仅仅复制权限
  • src:源文件路径,可以是Path对象或者字符串文件路径对象
  • dst:目标文件路径,可以是Path对象或者字符串文件路径对象
  • follow_symlinks:是否跟进链接文件。
  • True:表示拷贝链接文件所指向的文件
  • False:表示拷贝链接文件本身
  • copystat(src,dst,*,follow_symlinks=True) #拷贝文件元数据
  • src:源文件路径,可以是Path对象或者字符串文件路径对象
  • dst:目标文件路径,可以是Path对象或者字符串文件路径对象
  • follow_symlinks:是否跟进链接文件。
  • True:表示拷贝链接文件所指向的文件
  • False:表示拷贝链接文件本身
  • copy(src,dst,*,follow_symlinks=True) #复制文件内容和权限已经部分元数据,不包括创建和修改时间。
  • 本质上是调用的copyfile,和copymode
  • src:源文件
  • dst: 目标文件路径
  • follow_symlinks: 是否跟进链接文件
  • copy2(src,dst,*,follow_symlinks=True) #比copy多了复制全部元数据,但需要平台支撑。
  • 本质上调用的是copyfile,copystat
  • src:源文件
  • dst: 目标文件路径
  • follow_symlinks: 是否跟进链接文件
  • copytree(src,dst,symlinks=False,ignore=None,copy_function=copy2,ignore_dangling_symlinks=False) #递归拷贝文件
  • src:源文件路径,必须是目录,必须存在
  • dst: 目标文件路径,必须是目录,可以不是实际存在
  • symlinks: 是否拷贝链接文件本身,默认值为False 表示跟进链接文件。
  • False 拷贝链接文件所指向的文件
  • True 拷贝链接文件本身,不跟进链接文件。
  • ignore:是一个函数,提供一个callable(src,names)->ignored_names。用于过滤哪些条件的目录不需要拷贝。默认值为None表示不需要过滤,会默认生成一个空set()集合给ignored_names
  • collable(src,names)->ignored_names
  • src 源目录
  • names 是os.litdir(src)的结果,就是列出src中的文件名
  • ignored_names:要被过滤的文件名的set类型数据。
  • 原码中对应位置代码如下:

names = os.listdir(src)
if ignore is not None:
ignored_names = ignore(src, names)
else:
ignored_names = set()

os.makedirs(dst)
errors = []
for name in names:
if name in ignored_names:
continue
pass #后面代码这里省略,可以查看python中copytree原码

  • copy_function:是一个函数,默认为copy2拷贝函数,拷贝时带上文件元数据信息
  • ignore_dangling_symlinks: 链接文件所指向的文件不存在,是否出现异常,默认值为False
  • False: 表示,如果有异常,正常出现
  • True: 屏蔽链接文件所指向的文件不存在出现的异常
  • 综合简单示例:

import shutil,os
from pathlib import Path
h = Path("a/b/c/d")
h.mkdir(parents=True,exist_ok=True) #创建目录
h.parent.joinpath("e/").mkdir(parents=True,exist_ok=True)
h.parent.joinpath("f/").mkdir(parents=True,exist_ok=True)
names = ["a.txt","b.txt","c.txt","c2.txt","c3.txt","d.txt","b1.txt","b2.txt","a1.txt","a2.txt"]
for i in names: #创建文件
f = os.open(h.joinpath(i),os.O_CREAT)
os.close(f)
f = os.open(h.parent.joinpath(i),os.O_CREAT)
os.close(f)
f = os.open(h.parent.joinpath("e/",i),os.O_CREAT)
os.close(f)
f = os.open(h.parent.joinpath("f/",i),os.O_CREAT)
os.close(f)
#过滤以a开头和以c开头的文件。
fun = lambda src,name: {*filter(lambda name: name.startswith("a") or name.startswith("c"),names)}
#将a目录中的所有内容拷贝到b目录中
shutil.copytree(Path("a"),Path("b"),ignore=fun)

rm删除方法
  • shutil.rmtree(path,ignore_errors=False,οnerrοr=None) #递归删除,如同rm -rf一样危险,慎用。肯能会出现删除错误而中断,已经删除的就删除了。
  • path:要删除的路径对象
  • ignore_errors:是否忽略删除错误。默认为False表示不忽略。
  • True 忽略删除错误
  • False 不忽略删除错误,如果出现错误就终止,不过错误之前删除的文件已经删除。
  • onerror:是个函数,与ignore_errors结合使用。调用方式为:onerror(os.lstat, path, sys.exc_info())
  • 原码部分代码如下

if ignore_errors:
def onerror(*args):
pass
elif onerror is None:
def onerror(*args):
raise
# 部分代码省略

move移动方法
  • move(src,dst,copy_function=copy2) #移动文件或目录到目标,返回目标。
  • 本身使用的是os.rename方法。如果不支持rename方法,如果是目录就会使用copytree在删除源目录。默认使用copy2方法
  • src :源目录,或文件
  • dst :目标
  • copy_function :复制时的拷贝函数,默认为copy2
  • python源码如下:

def move(src, dst, copy_function=copy2):
real_dst = dst
if os.path.isdir(dst):
if _samefile(src, dst):
# We might be on a case insensitive filesystem,
# perform the rename anyway.
os.rename(src, dst)
return

real_dst = os.path.join(dst, _basename(src))
if os.path.exists(real_dst):
raise Error("Destination path '%s' already exists" % real_dst)
try:
os.rename(src, real_dst)
except OSError:
if os.path.islink(src):
linkto = os.readlink(src)
os.symlink(linkto, real_dst)
os.unlink(src)
elif os.path.isdir(src):
if _destinsrc(src, dst):
raise Error("Cannot move a directory '%s' into itself"
" '%s'." % (src, dst))
copytree(src, real_dst, copy_function=copy_function,
symlinks=True)
rmtree(src)
else:
copy_function(src, real_dst)
os.unlink(src)
return


举报

相关推荐

0 条评论