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 以最有效的方式。 srcdst 是以字符串形式给出的类似于路径的对象或路径名。

dst 必须是完整的目标文件名;请看 copy() 对于接受目标目录路径的副本。如果 srcdst 指定相同的文件, SameFileError 提高了。

目标位置必须是可写的;否则, OSError 将引发异常。如果 dst 已经存在,将被替换。不能使用此功能复制特殊文件,如字符或块设备和管道。

如果 follow_symlinks 是假的 src 是符号链接,将创建新的符号链接,而不是复制文件 src 指向。

提出一个 auditing event shutil.copyfile 带着论据 srcdst .

在 3.3 版更改: IOError 以前被引发而不是 OSError . 补充 follow_symlinks 参数。现在返回 dst .

在 3.4 版更改: 提高 SameFileError 而不是 Error . 由于前者是后者的一个子类,所以这种更改是向后兼容的。

在 3.8 版更改: 平台特定的快速复制系统调用可以在内部使用,以便更有效地复制文件。参见 依赖平台的高效复制操作 部分。

exception shutil.SameFileError

如果源和目标位于 copyfile() 是同一个文件。

3.4 新版功能.

shutil.copymode(src, dst, *, follow_symlinks=True)

从复制权限位 srcdst . 文件内容、所有者和组不受影响。 srcdst 是以字符串形式给出的类似于路径的对象或路径名。如果 follow_symlinks 都是假的 srcdst 是符号链接, copymode() 将尝试修改的模式 dst 本身(而不是它指向的文件)。此功能在每个平台上都不可用;请参阅 copystat() 更多信息。如果 copymode() 无法修改本地平台上的符号链接,并且要求它这样做,它将不做任何事情并返回。

提出一个 auditing event shutil.copymode 带着论据 srcdst .

在 3.3 版更改: 补充 follow_symlinks 参数。

shutil.copystat(src, dst, *, follow_symlinks=True)

从复制权限位、上次访问时间、上次修改时间和标志 srcdst . 在Linux上, copystat() 如果可能,还复制“扩展属性”。文件内容、所有者和组不受影响。 srcdst 是以字符串形式给出的类似于路径的对象或路径名。

如果 follow_symlinks 是假的, srcdst 两者都是指符号链接, copystat() 将操作符号链接本身,而不是符号链接所指的从 src 符号链接,并将信息写入 dst 符号链接。

注解

并非所有平台都提供检查和修改符号链接的能力。python本身可以告诉您什么功能是本地可用的。

  • 如果 os.chmod in os.supports_follow_symlinksTruecopystat() 可以修改符号链接的权限位。

  • 如果 os.utime in os.supports_follow_symlinksTruecopystat() 可以修改符号链接的最后访问和修改时间。

  • 如果 os.chflags in os.supports_follow_symlinksTruecopystat() 可以修改符号链接的标志。 (os.chflags 并非所有平台都可用。)

在部分或全部功能不可用的平台上,当要求修改符号链接时, copystat() 会尽可能地复制。 copystat() 永不失败。

请看 os.supports_follow_symlinks 更多信息。

提出一个 auditing event shutil.copystat 带着论据 srcdst .

在 3.3 版更改: 补充 follow_symlinks Linux扩展属性的参数和支持。

shutil.copy(src, dst, *, follow_symlinks=True)

复制文件 src 到文件或目录 dst . srcdst 应该是 path-like objects 或者是绳子。如果 dst 指定将文件复制到的目录 dst 使用来自的基本文件名 src . 返回新创建文件的路径。

如果 follow_symlinks 是假的, src 是一个符号链接, dst 将创建为符号链接。如果 follow_symlinks 是真的 src 是一个符号链接, dst 将是文件的副本 src 是指。

copy() 复制文件数据和文件的权限模式(请参见 os.chmod() )。其他元数据(如文件的创建和修改时间)不被保留。要保留原始文件中的所有文件元数据,请使用 copy2() 相反。

提出一个 auditing event shutil.copyfile 带着论据 srcdst .

提出一个 auditing event shutil.copymode 带着论据 srcdst .

在 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 带着论据 srcdst .

提出一个 auditing event shutil.copystat 带着论据 srcdst .

在 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 带着论据 srcdst .

在 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 函数属性来确定哪种情况适用。

如果 出错 如果提供,则必须是可调用的,它接受三个参数: functionpath超越信息 .

第一个参数, function ,是引发异常的函数;它取决于平台和实现。第二个参数, path ,将是传递给的路径名 function . 第三个参数, 超越信息 ,将是返回的异常信息 sys.exc_info() . 由引发的异常 出错 不会被抓到。

提出一个 auditing event shutil.rmtree 带着论证 path .

在 3.3 版更改: 增加了一个symlink抗攻击版本,如果平台支持基于fd的功能,该版本将自动使用。

在 3.8 版更改: 在Windows上,在删除连接之前,将不再删除目录连接的内容。

指示当前平台和实现是否提供的symlink抗攻击版本 rmtree() .目前,这仅适用于支持基于fd的目录访问功能的平台。

3.3 新版功能.

shutil.move(src, dst, copy_function=copy2)

递归移动文件或目录( src )到另一个位置( dst )并返回目的地。

如果目标是现有目录,则 src 在该目录中移动。如果目标已经存在,但不是目录,则根据 os.rename() 语义学。

如果目标位于当前文件系统上,则 os.rename() 使用。否则, src 复制到 dst 使用 copy_function 然后移除。对于symlinks,指向目标的新symlink src 将在或创建为 dstsrc 将被删除。

如果 copy_function ,则它必须是接受两个参数的可调用函数 srcdst ,并将用于复制 srcdst 如果 os.rename() 不能使用。如果源是目录, copytree() 被调用,并将其传递给 copy_function() 。默认设置 copy_functioncopy2() 。使用 copy() 作为 copy_function 当无法同时复制元数据时,允许移动成功,但代价是不复制任何元数据。

提出一个 auditing event shutil.move 带着论据 srcdst .

在 3.3 版更改: 为外部文件系统添加了显式符号链接处理,从而使其适应GNU的行为 mv . 现在回报 dst .

在 3.5 版更改: 增加了 copy_function 关键字参数。

在 3.8 版更改: 平台特定的快速复制系统调用可以在内部使用,以便更有效地复制文件。参见 依赖平台的高效复制操作 部分。

在 3.9 版更改: 接受一 path-like object 对于两者 srcdst .

shutil.disk_usage(path)

将给定路径的磁盘使用率统计信息作为 named tuple 具有属性 全部的usedfree ,表示总空间、已用空间和可用空间的大小(以字节为单位)。 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 带着论据 pathusergroup .

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在查找可执行文件时使用的命令行为。此外,当发现 cmdpath , the PATHEXT 检查环境变量。例如,如果你调用 shutil.which("python")which() 威尔搜索 PATHEXT 知道它应该寻找 python.exepath 目录。例如,在Windows上:

>>> shutil.which("python")
'C:\\Python33\\python.EXE'

3.3 新版功能.

在 3.8 版更改: 这个 bytes 现在接受类型。如果 cmd 类型是 bytes ,结果类型也是 bytes .

exception shutil.Error

此异常收集在多文件操作期间引发的异常。为了 copytree() ,exception参数是3个元组的列表( SRCNEXdSTNDexception

依赖平台的高效复制操作

从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 格式。

还提供了创建和读取压缩和存档文件的高级实用程序。他们依靠 zipfiletarfile 模块。

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_dirroot_dir 一起。

root_dirbase_dir 两者都默认为当前目录。

如果 dry_run 为真,不创建存档,但将执行的操作将被记录到 logger .

ownergroup 创建tar存档时使用。默认情况下,使用当前所有者和组。

logger 必须是与兼容的对象 PEP 282 ,通常是 logging.Logger .

这个 verbose 参数未使用,已弃用。

提出一个 auditing event shutil.make_archive 带着论据 base_nameformatroot_dirbase_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 )从开始存档。其他参数作为关键字参数传递: ownergroupdry_runlogger (如通过) 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 带着论据 filenameextract_dirformat .

在 3.7 版更改: 接受一 path-like object 对于 filenameextract_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))

获取终端窗口的大小。

对于两个维度中的每一个,环境变量, COLUMNSLINES 分别检查。如果定义了变量,并且该值为正整数,则使用该变量。

什么时候? COLUMNSLINES 未定义,这是常见情况,终端连接到 sys.__stdout__ 通过调用查询 os.get_terminal_size() .

如果由于系统不支持查询,或者由于我们没有连接到终端,无法成功查询终端大小,则在 fallback 使用了参数。 fallback 默认为 (80, 24) 这是许多终端仿真器使用的默认大小。

返回的值是类型为的命名元组 os.terminal_size .

另请参见:单一Unix规范,版本2, Other Environment Variables .

3.3 新版功能.