10.10. shutil — 高级文件操作 — Python 文档
10.10. 休蒂尔 — 高级文件操作
shutil 模块提供了许多对文件和文件集合的高级操作。 特别是提供了支持文件复制和删除的功能。 对于单个文件的操作,另见 os 模块。
警告
即使是更高级别的文件复制功能(shutil.copy(), shutil.copy2())也无法复制所有文件元数据。
在 POSIX 平台上,这意味着文件所有者和组以及 ACL 都将丢失。 在 Mac OS 上,不使用资源分支和其他元数据。 这意味着资源将丢失,文件类型和创建者代码将不正确。 在 Windows 上,不会复制文件所有者、ACL 和备用数据流。
10.10.1. 目录和文件操作
- shutil.copyfileobj(fsrc, fdst[, length])
- 将类文件对象 fsrc 的内容复制到类文件对象 fdst。 整数 length(如果给定)是缓冲区大小。 特别是,负 length 值意味着复制数据而不在块中循环遍历源数据; 默认情况下,数据是分块读取的,以避免不受控制的内存消耗。 注意,如果fsrc对象的当前文件位置不为0,则只会复制从当前文件位置到文件末尾的内容。
- shutil.copyfile(src, dst)
- 将名为 src 的文件的内容(无元数据)复制到名为 dst 的文件中。 dst 必须是完整的目标文件名; 查看 shutil.copy() 以获取接受目标目录路径的副本。 如果 src 和 dst 是相同的文件,则会引发 Error。 目标位置必须是可写的; 否则,将引发
IOError
异常。 如果 dst 已经存在,它将被替换。 使用此功能无法复制特殊文件,例如字符或块设备和管道。 src 和 dst 是以字符串形式给出的路径名。
- shutil.copymode(src, dst)
- 将权限位从 src 复制到 dst。 文件内容、所有者和组不受影响。 src 和 dst 是以字符串形式给出的路径名。
- shutil.copystat(src, dst)
- 将权限位、上次访问时间、上次修改时间和标志从 src 复制到 dst。 文件内容、所有者和组不受影响。 src 和 dst 是以字符串形式给出的路径名。
- shutil.copy(src, dst)
- 将文件src复制到文件或目录dst。 如果 dst 是目录,则在指定目录中创建(或覆盖)与 src 具有相同基名的文件。 复制权限位。 src 和 dst 是以字符串形式给出的路径名。
- shutil.copy2(src, dst)
与 copy() 相同,除了 copy2() 也尝试保留文件元数据。
copy2() 使用 copystat() 复制文件元数据。 请参阅 copystat() 了解更多信息。
- shutil.ignore_patterns(\*patterns)
此工厂函数创建一个函数,该函数可用作 copytree()' 的 ignore 参数的可调用函数,忽略与 glob 样式 之一匹配的文件和目录] 模式 提供。 请参阅下面的示例。
2.6 版中的新功能。
- shutil.copytree(src, dst, symlinks=False, ignore=None)
递归复制以 src 为根的整个目录树。 以dst命名的目标目录必须不存在; 它将被创建以及丢失的父目录。 使用copystat()复制目录的权限和时间,使用shutil.copy2()复制单个文件。
如果 symlinks 为真,则源树中的符号链接在新树中表示为符号链接,但不会复制原始链接的元数据; 如果为 false 或省略,则链接文件的内容和元数据将复制到新树中。
如果给出 ignore,则它必须是一个可调用对象,它将接收 copytree() 访问的目录作为其参数,以及 返回的内容列表os.listdir()。 由于 copytree() 是递归调用的,因此每个复制的目录都会调用一次 ignore 可调用对象。 可调用对象必须返回相对于当前目录的目录和文件名序列(即 第二个参数中项目的子集); 这些名称将在复制过程中被忽略。 ignore_patterns() 可用于创建这样一个忽略基于 glob 样式模式的名称的可调用对象。
如果发生异常,则会引发 Error 并列出原因。
应将其源代码视为示例而不是最终工具。
在 2.3 版更改:如果在复制过程中发生任何异常,而不是打印消息,则会引发 Error。
2.5 版更改: 创建创建 dst 所需的中间目录,而不是引发错误。 使用 copystat() 复制目录的权限和时间。
在 2.6 版中更改: 添加了 ignore 参数以能够影响正在复制的内容。
- shutil.rmtree(path[, ignore_errors[, onerror]])
删除整个目录树; path 必须指向一个目录(但不是指向目录的符号链接)。 如果 ignore_errors 为真,则删除失败导致的错误将被忽略; 如果为 false 或省略,则通过调用由 onerror 指定的处理程序来处理此类错误,或者,如果省略,则引发异常。
如果提供了 onerror,它必须是一个接受三个参数的可调用对象:function、path 和 excinfo。 第一个参数 function 是引发异常的函数; 它将是 os.path.islink()、os.listdir()、os.remove() 或 os.rmdir()[ X183X]。 第二个参数 path 将是传递给 function 的路径名。 第三个参数excinfo是sys.exc_info()返回的异常信息。 不会捕获由 onerror 引发的异常。
在 2.6 版更改: 明确检查 path 是否为符号链接并在这种情况下引发
OSError
。
- shutil.move(src, dst)
递归地将文件或目录 (src) 移动到另一个位置 (dst)。
如果目标是现有目录,则将 src 移动到该目录中。 如果目标已经存在但不是目录,则可能会根据 os.rename() 语义被覆盖。
如果目标在当前文件系统上,则使用 os.rename()。 否则,将 src 复制(使用 shutil.copy2())到 dst,然后删除。
2.3 版中的新功能。
- exception shutil.Error
此异常收集在多文件操作期间引发的异常。 对于 copytree(),异常参数是一个 3 元组列表(srcname, dstname, exception)。
2.3 版中的新功能。
10.10.1.1。 复制树示例
这个例子是上面描述的 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() 助手的示例:
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. 归档操作
还提供了用于创建和读取压缩和存档文件的高级实用程序。 它们依赖于 zipfile 和 tarfile 模块。
- shutil.make_archive(base_name, format[, root_dir[, base_dir[, verbose[, dry_run[, owner[, group[, logger]]]]]]])
创建一个存档文件(例如。 zip 或 tar)并返回其名称。
base_name 是要创建的文件的名称,包括路径,减去任何特定于格式的扩展名。 format 是存档格式:“zip”之一(如果 zlib 模块或外部
zip
可执行文件可用)、“tar”、“gztar”(如果zlib 模块可用)或“bztar”(如果 bz2 模块可用)。root_dir 是一个目录,它将成为存档的根目录; IE。 我们通常在创建存档之前 chdir 进入 root_dir。
base_dir 是我们开始归档的目录; IE。 base_dir 将是存档中所有文件和目录的公共前缀。
root_dir 和 base_dir 都默认为当前目录。
创建 tar 存档时使用 owner 和 group。 默认情况下,使用当前所有者和组。
logger 必须是与 PEP 282 兼容的对象,通常是 logging.Logger 的实例。
2.7 版中的新功能。
- shutil.get_archive_formats()
返回支持的归档格式列表。 返回序列的每个元素都是一个元组
(name, description)
。默认情况下 shutil 提供以下格式:
zip:ZIP 文件(如果 zlib 模块或外部
zip
可执行文件可用)。tar:未压缩的 tar 文件。
gztar:gzip 压缩的 tar 文件(如果 zlib 模块可用)。
bztar:bzip2 压缩的 tar 文件(如果 bz2 模块可用)。
您可以使用 register_archive_format() 注册新格式或为任何现有格式提供您自己的存档器。
2.7 版中的新功能。
- shutil.register_archive_format(name, function[, extra_args[, description]])
为 name 格式注册存档器。 function 是一个可调用的,用于调用归档器。
如果给定,extra_args 是一个
(name, value)
的序列,当使用存档器可调用时,它将用作额外的关键字参数。description 由 get_archive_formats() 使用,它返回存档器列表。 默认为空列表。
2.7 版中的新功能。
- shutil.unregister_archive_format(name)
从支持的格式列表中删除存档格式 name。
2.7 版中的新功能。
10.10.2.1。 归档示例
在此示例中,我们创建了一个 gzip 压缩的 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