shutil
---高级文件操作¶
源代码: Lib/shutil.py
这个 shutil
模块提供了许多关于文件和文件集合的高级操作。特别是,提供了支持文件复制和删除的功能。有关单个文件的操作,请参见 os
模块。
警告
甚至更高级的文件复制功能 (shutil.copy()
, shutil.copy2()
)无法复制所有文件元数据。
在POSIX平台上,这意味着文件所有者和组以及ACL都将丢失。在Mac OS上,不使用资源叉和其他元数据。这意味着资源将丢失,文件类型和创建者代码将不正确。在Windows上,不会复制文件所有者、ACL和备用数据流。
目录和文件操作¶
- shutil.copyfileobj(fsrc, fdst[, length])¶
复制类似对象的文件内容 fsrc 像文件一样的对象 fdst . 整数 长度 如果给定,则为缓冲区大小。尤其是一个否定的 长度 值意味着复制数据,而不以块的形式循环源数据;默认情况下,数据以块的形式读取,以避免不受控制的内存消耗。注意,如果当前文件位置 fsrc 对象不是0,将只复制从当前文件位置到文件结尾的内容。
- shutil.copyfile(src, dst, *, follow_symlinks=True)¶
复制名为的文件的内容(无元数据) src 命名为文件 dst 然后返回 dst 以最有效的方式。 src 和 dst 是以字符串形式给出的类似于路径的对象或路径名。
dst 必须是完整的目标文件名;请看
copy()
对于接受目标目录路径的副本。如果 src 和 dst 指定相同的文件,SameFileError
提高了。目标位置必须是可写的;否则,
OSError
将引发异常。如果 dst 已经存在,将被替换。不能使用此功能复制特殊文件,如字符或块设备和管道。如果 follow_symlinks 是假的 src 是符号链接,将创建新的符号链接,而不是复制文件 src 指向。
提出一个 auditing event
shutil.copyfile
带着论据src
,dst
.在 3.4 版更改: 提高
SameFileError
而不是Error
. 由于前者是后者的一个子类,所以这种更改是向后兼容的。在 3.8 版更改: 平台特定的快速复制系统调用可以在内部使用,以便更有效地复制文件。参见 依赖平台的高效复制操作 部分。
- exception shutil.SameFileError¶
如果源和目标位于
copyfile()
是同一个文件。3.4 新版功能.
- shutil.copymode(src, dst, *, follow_symlinks=True)¶
从复制权限位 src 到 dst . 文件内容、所有者和组不受影响。 src 和 dst 是以字符串形式给出的类似于路径的对象或路径名。如果 follow_symlinks 都是假的 src 和 dst 是符号链接,
copymode()
将尝试修改的模式 dst 本身(而不是它指向的文件)。此功能在每个平台上都不可用;请参阅copystat()
更多信息。如果copymode()
无法修改本地平台上的符号链接,并且要求它这样做,它将不做任何事情并返回。提出一个 auditing event
shutil.copymode
带着论据src
,dst
.在 3.3 版更改: 补充 follow_symlinks 参数。
- shutil.copystat(src, dst, *, follow_symlinks=True)¶
从复制权限位、上次访问时间、上次修改时间和标志 src 到 dst . 在Linux上,
copystat()
如果可能,还复制“扩展属性”。文件内容、所有者和组不受影响。 src 和 dst 是以字符串形式给出的类似于路径的对象或路径名。如果 follow_symlinks 是假的, src 和 dst 两者都是指符号链接,
copystat()
将操作符号链接本身,而不是符号链接所指的从 src 符号链接,并将信息写入 dst 符号链接。注解
并非所有平台都提供检查和修改符号链接的能力。python本身可以告诉您什么功能是本地可用的。
如果
os.chmod in os.supports_follow_symlinks
是True
,copystat()
可以修改符号链接的权限位。如果
os.utime in os.supports_follow_symlinks
是True
,copystat()
可以修改符号链接的最后访问和修改时间。如果
os.chflags in os.supports_follow_symlinks
是True
,copystat()
可以修改符号链接的标志。 (os.chflags
并非所有平台都可用。)
在部分或全部功能不可用的平台上,当要求修改符号链接时,
copystat()
会尽可能地复制。copystat()
永不失败。请看
os.supports_follow_symlinks
更多信息。提出一个 auditing event
shutil.copystat
带着论据src
,dst
.在 3.3 版更改: 补充 follow_symlinks Linux扩展属性的参数和支持。
- shutil.copy(src, dst, *, follow_symlinks=True)¶
复制文件 src 到文件或目录 dst . src 和 dst 应该是 path-like objects 或者是绳子。如果 dst 指定将文件复制到的目录 dst 使用来自的基本文件名 src . 返回新创建文件的路径。
如果 follow_symlinks 是假的, src 是一个符号链接, dst 将创建为符号链接。如果 follow_symlinks 是真的 src 是一个符号链接, dst 将是文件的副本 src 是指。
copy()
复制文件数据和文件的权限模式(请参见os.chmod()
)。其他元数据(如文件的创建和修改时间)不被保留。要保留原始文件中的所有文件元数据,请使用copy2()
相反。提出一个 auditing event
shutil.copyfile
带着论据src
,dst
.提出一个 auditing event
shutil.copymode
带着论据src
,dst
.在 3.3 版更改: 补充 follow_symlinks 参数。现在返回新创建文件的路径。
在 3.8 版更改: 平台特定的快速复制系统调用可以在内部使用,以便更有效地复制文件。参见 依赖平台的高效复制操作 部分。
- shutil.copy2(src, dst, *, follow_symlinks=True)¶
相同的
copy()
除了那个copy2()
还尝试保留文件元数据。什么时候? follow_symlinks 是假的, src 是一个符号链接,
copy2()
尝试从中复制所有元数据 src 到新创建的 dst 符号链接。但是,并非所有平台都具有此功能。在部分或全部功能不可用的平台上,copy2()
将保留它能保存的所有元数据;copy2()
从不引发异常,因为它无法保留文件元数据。copy2()
使用copystat()
复制文件元数据。请看copystat()
有关修改符号链接元数据的平台支持的详细信息。提出一个 auditing event
shutil.copyfile
带着论据src
,dst
.提出一个 auditing event
shutil.copystat
带着论据src
,dst
.在 3.3 版更改: 补充 follow_symlinks 参数,也尝试复制扩展文件系统属性(当前仅限Linux)。现在返回新创建文件的路径。
在 3.8 版更改: 平台特定的快速复制系统调用可以在内部使用,以便更有效地复制文件。参见 依赖平台的高效复制操作 部分。
- shutil.ignore_patterns(*patterns)¶
此factory函数创建一个函数,该函数可以用作
copytree()
的 忽视 参数,忽略与glob样式之一匹配的文件和目录 模式 提供。请参见下面的示例。
- shutil.copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False, dirs_exist_ok=False)¶
以递归方式复制根位于的整个目录树 src 到一个名为 dst 并返回目标目录。 dirs_exist_ok 指示是否引发异常以防 dst 或者任何丢失的父目录已经存在。
目录的权限和时间是用复制的
copystat()
,使用copy2()
.如果 交汇点 如果为真,则源码树中的符号链接在新树中表示为符号链接,并在平台允许的范围内复制原始链接的元数据;如果为假或忽略,则将链接文件的内容和元数据复制到新树中。
什么时候? 交汇点 为false,如果symlink指向的文件不存在,则在
Error
复制过程结束时出现异常。您可以设置选项 ignore_dangling_symlinks 如果要使此异常安静,则将标记为“真”。请注意,此选项对不支持的平台没有影响os.symlink()
.如果 忽视 如果给定,则它必须是一个可调用的,它将接收被访问的目录作为其参数。
copytree()
以及由返回的内容列表os.listdir()
. 自从copytree()
以递归方式调用, 忽视 对于复制的每个目录,将调用一次Callable。可调用文件必须返回相对于当前目录的一系列目录和文件名(即第二个参数中的一个子集);然后在复制过程中将忽略这些名称。ignore_patterns()
可用于创建这样一个可调用文件,该文件忽略基于全局样式模式的名称。如果发生异常,则
Error
提出了一系列原因。如果 copy_function 如果给定,则必须是一个可调用文件,用于复制每个文件。它将以源路径和目标路径作为参数进行调用。默认情况下,
copy2()
使用,但任何支持相同签名的函数(如copy()
可以使用。提出一个 auditing event
shutil.copytree
带着论据src
,dst
.在 3.3 版更改: 复制元数据的时间 交汇点 是假的。现在回报 dst .
在 3.2 版更改: 增加了 copy_function 能够提供自定义复制函数的参数。增加了 ignore_dangling_symlinks 静音悬挂符号链接错误的参数 交汇点 是假的。
在 3.8 版更改: 平台特定的快速复制系统调用可以在内部使用,以便更有效地复制文件。参见 依赖平台的高效复制操作 部分。
3.8 新版功能: 这个 dirs_exist_ok 参数。
- shutil.rmtree(path, ignore_errors=False, onerror=None)¶
删除整个目录树; path 必须指向目录(但不是指向目录的符号链接)。如果 ignore_errors 如果为true,则将忽略由于删除失败而导致的错误;如果为false或省略,则通过调用由指定的处理程序来处理这些错误。 出错 或者,如果忽略了这一点,他们就会提出一个例外。
注解
在支持必要的基于fd的功能的平台上,symlink抗攻击版本
rmtree()
默认情况下使用。在其他平台上,rmtree()
实现容易受到symlink攻击:在适当的时间和情况下,攻击者可以操纵文件系统上的symlink来删除他们无法访问的文件。应用程序可以使用rmtree.avoids_symlink_attacks
函数属性来确定哪种情况适用。如果 出错 如果提供,则必须是可调用的,它接受三个参数: function , path 和 超越信息 .
第一个参数, function ,是引发异常的函数;它取决于平台和实现。第二个参数, path ,将是传递给的路径名 function . 第三个参数, 超越信息 ,将是返回的异常信息
sys.exc_info()
. 由引发的异常 出错 不会被抓到。提出一个 auditing event
shutil.rmtree
带着论证path
.在 3.3 版更改: 增加了一个symlink抗攻击版本,如果平台支持基于fd的功能,该版本将自动使用。
在 3.8 版更改: 在Windows上,在删除连接之前,将不再删除目录连接的内容。
- shutil.move(src, dst, copy_function=copy2)¶
递归移动文件或目录( src )到另一个位置( dst )并返回目的地。
如果目标是现有目录,则 src 在该目录中移动。如果目标已经存在,但不是目录,则根据
os.rename()
语义学。如果目标位于当前文件系统上,则
os.rename()
使用。否则, src 复制到 dst 使用 copy_function 然后移除。对于symlinks,指向目标的新symlink src 将在或创建为 dst 和 src 将被删除。如果 copy_function ,则它必须是接受两个参数的可调用函数 src 和 dst ,并将用于复制 src 至 dst 如果
os.rename()
不能使用。如果源是目录,copytree()
被调用,并将其传递给copy_function()
。默认设置 copy_function 是copy2()
。使用copy()
作为 copy_function 当无法同时复制元数据时,允许移动成功,但代价是不复制任何元数据。提出一个 auditing event
shutil.move
带着论据src
,dst
.在 3.3 版更改: 为外部文件系统添加了显式符号链接处理,从而使其适应GNU的行为 mv . 现在回报 dst .
在 3.5 版更改: 增加了 copy_function 关键字参数。
在 3.8 版更改: 平台特定的快速复制系统调用可以在内部使用,以便更有效地复制文件。参见 依赖平台的高效复制操作 部分。
在 3.9 版更改: 接受一 path-like object 对于两者 src 和 dst .
- shutil.disk_usage(path)¶
将给定路径的磁盘使用率统计信息作为 named tuple 具有属性 全部的 , used 和 free ,表示总空间、已用空间和可用空间的大小(以字节为单位)。 path 可以是文件或目录。
3.3 新版功能.
在 3.8 版更改: 在Windows上, path 现在可以是文件或目录。
Availability :Unix、Windows。
- shutil.chown(path, user=None, group=None)¶
变更所有者 user 和/或 group 给定的 path .
user 可以是系统用户名或uid;同样适用于 group . 至少需要一个参数。
也见
os.chown()
,基础函数。提出一个 auditing event
shutil.chown
带着论据path
,user
,group
.Availability UNIX。
3.3 新版功能.
- shutil.which(cmd, mode=os.F_OK | os.X_OK, path=None)¶
返回一个可执行文件的路径,如果给定的 cmd 被叫来。如果没有 cmd 会被叫回来的
None
.mode 是否将权限掩码传递给
os.access()
,默认情况下,确定文件是否存在并可执行。当没有 path 是指定的,结果为
os.environ()
使用,返回“path”值或os.defpath
.在Windows上,当前目录总是在 path 无论您是否使用默认值或提供自己的,这是shell在查找可执行文件时使用的命令行为。此外,当发现 cmd 在 path , the
PATHEXT
检查环境变量。例如,如果你调用shutil.which("python")
,which()
威尔搜索PATHEXT
知道它应该寻找python.exe
内 path 目录。例如,在Windows上:>>> shutil.which("python") 'C:\\Python33\\python.EXE'
3.3 新版功能.
- exception shutil.Error¶
此异常收集在多文件操作期间引发的异常。为了
copytree()
,exception参数是3个元组的列表( SRCNEX , dSTND , exception )
依赖平台的高效复制操作¶
从python 3.8开始,所有涉及文件复制的函数 (copyfile()
, copy()
, copy2()
, copytree()
和 move()
)可以使用特定于平台的“快速复制”系统调用,以便更高效地复制文件(请参见 bpo-33671 ““快速复制”意味着复制操作发生在内核中,避免在python中使用“outdd.write(infd.read())`”中的用户空间缓冲区。
论马科斯 fcopyfile 用于复制文件内容(而不是元数据)。
在Linux上 os.sendfile()
使用。
在Windows上 shutil.copyfile()
使用更大的默认缓冲区大小(1 mib而不是64 kib)和 memoryview()
-基于的变量 shutil.copyfileobj()
使用。
如果快速复制操作失败并且目标文件中没有写入任何数据,则shutil将以不太高效的方式自动回退。 copyfileobj()
内部功能。
在 3.8 版更改.
复制树示例¶
这个例子是 copytree()
函数,如上所述,省略docstring。它演示了该模块提供的许多其他功能。::
def copytree(src, dst, symlinks=False):
names = os.listdir(src)
os.makedirs(dst)
errors = []
for name in names:
srcname = os.path.join(src, name)
dstname = os.path.join(dst, name)
try:
if symlinks and os.path.islink(srcname):
linkto = os.readlink(srcname)
os.symlink(linkto, dstname)
elif os.path.isdir(srcname):
copytree(srcname, dstname, symlinks)
else:
copy2(srcname, dstname)
# XXX What about devices, sockets etc.?
except OSError as why:
errors.append((srcname, dstname, str(why)))
# catch the Error from the recursive copytree so that we can
# continue with other files
except Error as err:
errors.extend(err.args[0])
try:
copystat(src, dst)
except OSError as why:
# can't copy file access times on Windows
if why.winerror is None:
errors.extend((src, dst, str(why)))
if errors:
raise Error(errors)
另一个使用 ignore_patterns()
帮手::
from shutil import copytree, ignore_patterns
copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))
这将复制除 .pyc
名称以开头的文件和文件或目录 tmp
.
另一个使用 忽视 用于添加日志记录调用的参数::
from shutil import copytree
import logging
def _logpath(path, names):
logging.info('Working in %s', path)
return [] # nothing will be ignored
copytree(source, destination, ignore=_logpath)
rmtree示例¶
此示例演示如何删除Windows上的目录树,其中一些文件设置了只读位。它使用onerror回调清除只读位并重新尝试删除。任何随后的故障都将传播。::
import os, stat
import shutil
def remove_readonly(func, path, _):
"Clear the readonly bit and reattempt the removal"
os.chmod(path, stat.S_IWRITE)
func(path)
shutil.rmtree(directory, onerror=remove_readonly)
归档操作¶
3.2 新版功能.
在 3.5 版更改: 增加了对 xztar 格式。
还提供了创建和读取压缩和存档文件的高级实用程序。他们依靠 zipfile
和 tarfile
模块。
- shutil.make_archive(base_name, format[, root_dir[, base_dir[, verbose[, dry_run[, owner[, group[, logger]]]]]]])¶
创建一个存档文件(如zip或tar)并返回其名称。
base_name 要创建的文件的名称,包括路径,减去任何特定于格式的扩展名。 格式 是存档格式:“zip”之一(如果
zlib
模块可用)、“tar”、“gztar”(如果zlib
模块可用),“BZTAR”(如果bz2
模块可用)或“XZTAR”(如果lzma
模块可用)。root_dir 是将作为存档的根目录的目录,存档中的所有路径都将与之相关;例如,我们通常将chdir root_dir 在创建存档之前。
base_dir 是我们开始存档的目录;即 base_dir 将是存档中所有文件和目录的通用前缀。 base_dir 必须相对于 root_dir . 见 存档示例 base_dir 如何使用 base_dir 和 root_dir 一起。
root_dir 和 base_dir 两者都默认为当前目录。
如果 dry_run 为真,不创建存档,但将执行的操作将被记录到 logger .
owner 和 group 创建tar存档时使用。默认情况下,使用当前所有者和组。
logger 必须是与兼容的对象 PEP 282 ,通常是
logging.Logger
.这个 verbose 参数未使用,已弃用。
提出一个 auditing event
shutil.make_archive
带着论据base_name
,format
,root_dir
,base_dir
.在 3.8 版更改: 现在使用的是现代pax(posix.1-2001)格式,而不是用传统的gnu格式创建的档案。
format="tar"
.
- shutil.get_archive_formats()¶
返回支持的存档格式列表。返回序列的每个元素都是一个元组
(name, description)
.默认情况下
shutil
提供以下格式:zip :zip文件(如果
zlib
模块可用)。tar :未压缩的tar文件。对新档案使用posix.1-2001 pax格式。
gztar :gzip'ed tar文件(如果
zlib
模块可用)。bztar :bzip2'ed tar文件(如果
bz2
模块可用)。xztar :xz'ed tar文件(如果
lzma
模块可用)。
您可以注册新格式或为任何现有格式提供自己的存档程序,方法是使用
register_archive_format()
.
- shutil.register_archive_format(name, function[, extra_args[, description]])¶
为格式注册存档程序 name .
function 是用于解包存档的可调用文件。调用方将收到 base_name 要创建的文件,然后是 base_dir (默认为
os.curdir
)从开始存档。其他参数作为关键字参数传递: owner , group , dry_run 和 logger (如通过)make_archive()
)如果给出的话, extra_args 是一个序列
(name, value)
当使用archive可调用文件时,将用作额外关键字参数的对。description 被使用
get_archive_formats()
它返回存档程序列表。默认为空字符串。
- shutil.unregister_archive_format(name)¶
删除存档格式 name 从支持的格式列表中。
- shutil.unpack_archive(filename[, extract_dir[, format]])¶
打开存档。 filename 是存档的完整路径。
extract_dir 是解包存档文件的目标目录的名称。如果未提供,则使用当前工作目录。
格式 是存档格式:“zip”、“tar”、“gztar”、“bztar”或“xztar”之一。或注册的任何其他格式
register_unpack_format()
. 如果没有提供,unpack_archive()
将使用存档文件扩展名,并查看是否为该扩展名注册了解包程序。如果没有找到,则ValueError
提高了。提出一个 auditing event
shutil.unpack_archive
带着论据filename
,extract_dir
,format
.在 3.7 版更改: 接受一 path-like object 对于 filename 和 extract_dir .
- shutil.register_unpack_format(name, extensions, function[, extra_args[, description]])¶
注册解包格式。 name 是格式的名称,并且 扩展 是与格式相对应的扩展名列表,如
.zip
用于zip文件。function 是用于解包存档的可调用文件。可调用文件将接收存档文件的路径,后跟存档文件必须提取到的目录。
如果提供, extra_args 是一个序列
(name, value)
将作为关键字参数传递给可调用文件的元组。description 可用于描述格式,并将由
get_unpack_formats()
功能。
- shutil.unregister_unpack_format(name)¶
注销解包格式。 name 是格式的名称。
- shutil.get_unpack_formats()¶
返回所有已注册的解包格式的列表。返回序列的每个元素都是一个元组
(name, extensions, description)
.默认情况下
shutil
提供以下格式:zip :zip文件(仅当相应模块可用时,解包压缩文件才有效)。
tar :未压缩的tar文件。
gztar :gzip'ed tar文件(如果
zlib
模块可用)。bztar :bzip2'ed tar文件(如果
bz2
模块可用)。xztar :xz'ed tar文件(如果
lzma
模块可用)。
您可以注册新格式或为任何现有格式提供自己的解包程序,方法是使用
register_unpack_format()
.
存档示例¶
在本例中,我们创建一个gzip'ed tar文件存档,其中包含在 .ssh
用户目录:
>>> from shutil import make_archive
>>> import os
>>> archive_name = os.path.expanduser(os.path.join('~', 'myarchive'))
>>> root_dir = os.path.expanduser(os.path.join('~', '.ssh'))
>>> make_archive(archive_name, 'gztar', root_dir)
'/Users/tarek/myarchive.tar.gz'
生成的存档包含:
$ tar -tzvf /Users/tarek/myarchive.tar.gz
drwx------ tarek/staff 0 2010-02-01 16:23:40 ./
-rw-r--r-- tarek/staff 609 2008-06-09 13:26:54 ./authorized_keys
-rwxr-xr-x tarek/staff 65 2008-06-09 13:26:54 ./config
-rwx------ tarek/staff 668 2008-06-09 13:26:54 ./id_dsa
-rwxr-xr-x tarek/staff 609 2008-06-09 13:26:54 ./id_dsa.pub
-rw------- tarek/staff 1675 2008-06-09 13:26:54 ./id_rsa
-rw-r--r-- tarek/staff 397 2008-06-09 13:26:54 ./id_rsa.pub
-rw-r--r-- tarek/staff 37192 2010-02-06 18:23:10 ./known_hosts
存档示例 base_dir¶
在本例中,类似于 one above ,我们演示如何使用 make_archive()
,但这次使用 base_dir . 我们现在有以下目录结构:
$ tree tmp
tmp
└── root
└── structure
├── content
└── please_add.txt
└── do_not_add.txt
在最后的档案里, please_add.txt
应该包括在内,但是 do_not_add.txt
不应该。因此,我们采用以下方法:
>>> from shutil import make_archive
>>> import os
>>> archive_name = os.path.expanduser(os.path.join('~', 'myarchive'))
>>> make_archive(
... archive_name,
... 'tar',
... root_dir='tmp/root',
... base_dir='structure/content',
... )
'/Users/tarek/my_archive.tar'
在生成的归档文件中列出这些文件,我们可以:
$ python -m tarfile -l /Users/tarek/myarchive.tar
structure/content/
structure/content/please_add.txt
查询输出终端的大小¶
- shutil.get_terminal_size(fallback=(columns, lines))¶
获取终端窗口的大小。
对于两个维度中的每一个,环境变量,
COLUMNS
和LINES
分别检查。如果定义了变量,并且该值为正整数,则使用该变量。什么时候?
COLUMNS
或LINES
未定义,这是常见情况,终端连接到sys.__stdout__
通过调用查询os.get_terminal_size()
.如果由于系统不支持查询,或者由于我们没有连接到终端,无法成功查询终端大小,则在
fallback
使用了参数。fallback
默认为(80, 24)
这是许多终端仿真器使用的默认大小。返回的值是类型为的命名元组
os.terminal_size
.另请参见:单一Unix规范,版本2, Other Environment Variables .
3.3 新版功能.