10.10. shutil高级的文件操作

源程序代码:Lib/shutil.py


Shutil模块提供了许多高级别操作对文件和文件的集合。尤其是,函数提供哪些支持文件复制和删除。对单个文件的操作,请参阅操作系统的模块。

警告

甚至更高层次的文件复制功能 (shutil.copy() shutil.copy2()) 无法复制文件的所有元数据。

在 POSIX 平台上,这意味着文件所有者和组将丢失以及 Acl。在 Mac OS 中,不使用的资源分叉和其他元数据。这意味着资源将会丢失,文件类型和创建者代码不会正确。在 Windows 上,不复制文件所有者、 Acl 和备用数据流。

10.10.1. Directory and files operations

shutil.copyfileobj(fsrc, fdst[, length])

将文件类似物体金管会的内容复制到文件类似物体fdstThe integer length, if given, is the buffer size.尤其是,负的长度值意味着要复制的数据,但不存在循环块 ; 中的源数据默认情况下,数据是以块的方式读取,以避免无节制的内存消耗。请注意,如果fsrc对象的当前文件位置不为0,则只复制当前文件位置到文件末尾的内容。

shutil.copyfile(src, dst)

文件命名为src到名为dst文件副本内容 (没有元数据)。dst必须完成目标文件的名称 ;看看shutil.copy()接受目标目录路径的副本。如果srcdst是相同的文件,则会引发错误目标位置必须是可写的 ;否则,将引发异常时发生 io 错误如果dst已经存在,它将被替换。如字符或块设备和管道的特殊文件无法复制使用此函数。srcdst是作为字符串给出的路径名称。

shutil.copymode(src, dst)

将权限位从src复制到dst文件内容、 所有者和组会受到影响。srcdst是作为字符串给出的路径名称。

shutil.copystat(src, dst)

将权限位、 最后存取时间、 最后修改时间和标志从src复制到dst文件内容、 所有者和组会受到影响。srcdst是作为字符串给出的路径名称。

shutil.copy(src, dst)

对文件或目录复制文件src dst如果dst是一个目录,具有相同的 basename 称为src的文件是创建 (或覆盖) 指定的目录中。复制权限位。srcdst是作为字符串给出的路径名称。

shutil.copy2(src, dst)

类似于shutil.copy(),但元数据复制以及 — — 事实上,这是只是shutil.copy() ,其次是copystat()这是类似于 Unix 的命令cp-p

shutil.ignore_patterns(*patterns)

此工厂函数创建一个函数,它可以作为可调用用于copytree()忽略参数,忽略文件和目录匹配提供的通配符匹配操作符风格模式之一。请参阅下面的示例。

在 2.6 版本新。

shutil.copytree(src, dst, symlinks=False, ignore=None)

以递归方式将复制整个目录树根植在src目标目录下,命名由dst,不必须已经存在 ;它将创建及失踪的父目录。copystat()复制权限和目录的时候,单个文件将被复制使用shutil.copy2()

如果syslinks为真,源树中的软链接表示为新树中的软链接,但不复制原始链接的元数据;如果为 false 或被省略,内容和元数据链接的文件复制到新树。

如果给定忽略,则它必须是可调用将接收作为其参数由os.listdir()返回后造访了copytree()和其内容的列表的目录。由于copytree()以递归方式调用,忽略可调用后,将调用的每个目录复制。可调用必须返回一个序列的目录和文件的名称,相对于当前目录 (即第二个参数中的项的子集) ;这些名称然后将在复制过程中被忽略。 ignore_patterns()可以用来创建这种忽略基于 glob 样式名称的调用。

如果异常发生,具有一系列原因引发的错误

一个例子,而不是最终的工具,应考虑为此源代码。

版本 2.3 中的更改:如果在复制,而不是打印一条消息的过程中发生的任何异常,将引发错误

2.5 版本中的更改:创建中介目录创建dst,所需,而不是引发错误。复制权限和目录使用copystat()倍。

2.6 版本中的更改:添加的忽略的参数,以便能够影响什么是复制的内容。

shutil.rmtree(path[, ignore_errors[, onerror]])

删除整个目录树;path必须指向一个目录(不可以是指向目录的软链接)。如果ignore_errors为真,将忽略删除失败产生的错误;如果为假或被省略,这些错误将通过调用onerror指示的处理程序处理,或者如果省略onerror,它们将会引发异常。

如果提供onerror,它必须是一个接受三个参数的可调用类似:functionpathexcinfo第一个参数function是引发异常的函数;它将会是os.path.islink()os.listdir() os.remove()os.rmdir()第二个参数path是传递给function的路径名称。第三个参数excinfo是由sys.exc_info()返回的异常信息。onerror抛出的异常不会被捕获。

2.6 版本中的更改:明确检查path是否是一个符号链接,在这种情况下将引发OSError

shutil.move(src, dst)

以递归方式移动文件或目录(src)到另一个位置(dst)。

如果目标是一个目录或一个目录的符号链接,那么src被移动到该目录中。

目标目录必须已经存在。如果目标位置已存在,但不是一个目录,它可能根据os.rename()的语义被覆盖。

如果目标是在当前的文件系统上,则使用os.rename() 否则,将src复制到dst(使用shutil.copy2()),然后删除。

版本2.3中新增。

exception shutil.Error

此异常收集在多文件操作过程中引发的异常。对于copytree(),该异常的参数是一个三元组(srcname, dstname, exception)。

版本2.3中新增。

10.10.1.1. copytree example

这个例子是copytree()函数,上面所述,省略文档字符串的实现。它演示了很多此模块提供的其他功能。

def copytree(src, dst, symlinks=False, ignore=None):
    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
        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, ignore)
            else:
                copy2(srcname, dstname)
            # XXX What about devices, sockets etc.?
        except (IOError, os.error) 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 WindowsError:
        # can't copy file access times on Windows
        pass
    except OSError as why:
        errors.extend((src, dst, str(why)))
    if errors:
        raise Error(errors)

使用ignore_patterns() helper 的另一个示例:

from shutil import copytree, ignore_patterns

copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))

这将复制除.pyc文件和以名字tmp开头的文件或目录以外的所有内容。

使用ignore参数来添加日志调用的另一个示例:

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)

10.10.2. Archiving operations

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

shutil.make_archive(base_name, format[, root_dir[, base_dir[, verbose[, dry_run[, owner[, group[, logger]]]]]]])

创建存档文件 (如.zip 或者 tar) 并返回它的名称。

base_name是文件的要创建的名称包括路径,没有任何特定格式的扩展名。format是档案格式:"zip"、"tar"、"bztar"或"gztar"之一。

root_dir是档案的一个目录,将根目录下 ;ie。我们通常 chdir 入root_dir在创建归档文件之前。

base_dir是我们从哪里开始从 ; 存档的目录ie。base_dir将的公共前缀的所有文件和目录在存档中。

root_dirbase_dir两个默认为当前目录。

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

记录器必须是一个对象与兼容 PEP 282号通常的测井实例。记录器。

在 2.7 版本新。

shutil.get_archive_formats()

返回一个列表支持的格式,用于存档。所返回序列中的每个元素是一个元组(名称, 描述)

默认情况下shutil提供这些格式:

  • gztar: gzip’ed tar-file
  • bztar: bzip2’ed tar-file
  • tar: uncompressed tar file
  • zip: ZIP file

你可以注册新的格式,或通过使用register_archive_format(),对于任何现有的格式,提供您自己的归档。

在 2.7 版本新。

shutil.register_archive_format(name, function[, extra_args[, description]])

登记归档格式名称功能是将用于调用存档程序的调用。

如果给定, extra_args是一个序列的(名称, 值)使用存档程序可调用时将使用作为额外的关键字参数。

get_archive_formats()返回的行归档列表使用说明默认值为一个空的列表。

在 2.7 版本新。

shutil.unregister_archive_format(name)

从支持的格式列表中删除存档格式名称

在 2.7 版本新。

10.10.2.1. Archiving example

在此示例中,我们创建了包含用户的.ssh目录中找到的所有文件的只有 14kb 大小 tar 文件存档:

>>> 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