shutil-高级文件操作(10)Python文件和目录访问模块(必读进阶Python教程)(参考资料)
该shutil
模块对文件和文件集合提供了许多高级操作。特别是,提供了支持文件复制和删除的功能。有关单个文件的操作,另请参阅该 os
模块。
警告
即使是更高级别的文件复制功能(shutil.copy()
, shutil.copy2()
)也无法复制所有文件元数据。
在POSIX平台上,这意味着文件所有者和组以及ACL都会丢失。在Mac OS上,不使用资源分支和其他元数据。这意味着资源将丢失,文件类型和创建者代码将不正确。在Windows上,不会复制文件所有者,ACL和备用数据流。
目录和文件操作
shutil.
copyfileobj
(FSRC,fdst [,长度] )- 在类文件对象的内容复制金管会的文件对象fdst。如果给定,则整数长度是缓冲区大小。特别地,负 长度值意味着复制数据而不以块的形式循环源数据; 默认情况下,数据以块的形式读取,以避免不受控制的内存消耗。请注意,如果fsrc对象的当前文件位置不为0,则仅复制从当前文件位置到文件末尾的内容。
shutil.
copyfile
(src,dst,*,follow_symlinks = True )- 将名为src的文件的内容(无元数据)复制到名为dst的文件中 并返回dst。 src和dst是以字符串形式给出的路径名。 dst必须是完整的目标文件名; 查看
shutil.copy()
接受目标目录路径的副本。如果src和dst 指定相同的文件,SameFileError
则引发。目的地位置必须是可写的; 否则,
OSError
将引发例外。如果dst已经存在,它将被替换。使用此功能无法复制特殊文件,如字符或块设备和管道。如果follow_symlinks为false且src是符号链接,则将创建新的符号链接,而不是复制src指向的文件。
在版本3.3中更改:
IOError
曾经被提升而不是OSError
。添加了follow_symlinks参数。现在返回dst。在版本3.4中更改:提升
SameFileError
而不是Error
。由于前者是后者的子类,因此这种改变是向后兼容的。
- 异常
shutil.
SameFileError
- 如果source和destination in
copyfile()
是同一个文件,则会引发此异常。版本3.4中的新功能。
shutil.
copymode
(src,dst,*,follow_symlinks = True )- 将权限位从src复制到dst。文件内容,所有者和组不受影响。 src和dst是以字符串形式给出的路径名。如果follow_symlinks为false,并且src和dst都是符号链接,
copymode()
则会尝试修改dst本身的模式(而不是它指向的文件)。并非每个平台都提供此功能; 请参阅copystat()
更多信息。如果copymode()
无法修改本地平台上的符号链接,并且要求它这样做,它将不执行任何操作并返回。版本3.3中已更改:添加了follow_symlinks参数。
shutil.
copystat
(src,dst,*,follow_symlinks = True )- 复制权限位,上次访问时间,上次修改时间以及从src到dst的标志。在Linux上,
copystat()
还尽可能复制“扩展属性”。文件内容,所有者和组不受影响。 src和dst是以字符串形式给出的路径名。如果follow_symlinks为false,并且src和dst都引用符号链接,
copystat()
则将对符号链接本身进行操作,而不是符号链接引用的文件 – 从src符号链接读取信息 ,并将信息写入 dst符号链接。注意
并非所有平台都提供检查和修改符号链接的功能。Python本身可以告诉您本地可用的功能。
- 如果是 ,则可以修改符号链接的权限位。
os.chmod in os.supports_follow_symlinks
True
copystat()
- 如果是 ,则可以修改符号链接的上次访问和修改时间。
os.utime inos.supports_follow_symlinks
True
copystat()
- 如果是 ,可以修改符号链接的标志。(不适用于所有平台。)
os.chflags inos.supports_follow_symlinks
True
copystat()
os.chflags
在部分或全部此功能不可用的平台上,当要求修改符号链接时,
copystat()
将复制它可以执行的所有操作。copystat()
永远不会失败。请参阅
os.supports_follow_symlinks
更多信息。版本3.3中已更改:添加了follow_symlinks参数并支持Linux扩展属性。
- 如果是 ,则可以修改符号链接的权限位。
shutil.
copy
(src,dst,*,follow_symlinks = True )- 将文件src复制到文件或目录dst。 src和dst 应该是字符串。如果dst指定目录,则使用src中的基本文件名将文件复制到dst中。返回新创建文件的路径。
如果follow_symlinks为false,并且src是符号链接,则 dst将创建为符号链接。如果follow_symlinks 为true且src是符号链接,则dst将是src引用的文件的副本。
copy()
复制文件数据和文件的权限模式(请参阅参考资料os.chmod()
)。其他元数据(如文件的创建和修改时间)不会保留。要保留原始文件中的所有文件元数据,请copy2()
改用。版本3.3中已更改:添加了follow_symlinks参数。现在返回新创建文件的路径。
shutil.
copy2
(src,dst,*,follow_symlinks = True )copy()
除了copy2()
同样尝试保留文件元数据之外的相同内容。当follow_symlinks为false且src是符号链接时,
copy2()
尝试将所有元数据从src符号链接复制 到新创建的dst符号链接。但是,并非所有平台都提供此功能。在部分或全部此功能不可用的平台上,copy2()
将保留所有可用的元数据;copy2()
永远不会失败。copy2()
用于copystat()
复制文件元数据。copystat()
有关修改符号链接元数据的平台支持的更多信息,请参阅。版本3.3中更改:添加了follow_symlinks参数,尝试复制扩展文件系统属性(目前仅限Linux)。现在返回新创建文件的路径。
shutil.
ignore_patterns
(*模式)- 这个工厂函数创建一个可以作为一个可调用一个函数
copytree()
的忽略说法,忽略匹配通配符式样的一个文件和目录的方式提供。请参阅下面的示例。
shutil.
copytree
(src,dst,symlinks = False,ignore = None,copy_function = copy2,ignore_dangling_symlinks = False )- 递归复制以src为根的整个目录树,返回目标目录。目标目录(由dst命名)必须不存在; 它将被创建以及缺少父目录。复制目录的权限和时间,使用复制
copystat()
单个文件shutil.copy2()
。如果符号链接为真,则源树中的符号链接在新树中表示为符号链接,并且只要平台允许,将复制原始链接的元数据; 如果为false或省略,则链接文件的内容和元数据将复制到新树中。
当符号链接为false时,如果符号链接指向的文件不存在,则
Error
在复制过程结束时在异常中引发的错误列表中将添加异常。如果要使此异常静音,可以将可选的ignore_dangling_symlinks标志设置为true。请注意,此选项对不支持的平台没有影响os.symlink()
。如果给出了ignore,则它必须是一个可调用的,它将接收被访问的目录作为其参数
copytree()
,并返回其内容的列表os.listdir()
。由于copytree()
以递归方式调用,因此对于每个复制的目录,将调用ignore callable一次。callable必须返回相对于当前目录的一系列目录和文件名(即第二个参数中的项的子集); 这些名称将在复制过程中被忽略。ignore_patterns()
可以用来创建一个基于glob样式模式忽略名称的callable。如果发生异常,
Error
则会引发一系列原因。如果给出了copy_function,则它必须是可用于复制每个文件的可调用对象。它将使用源路径和目标路径作为参数进行调用。默认情况下,
shutil.copy2()
使用,但可以使用任何支持相同签名(如shutil.copy()
)的函数。在版本3.3中更改:在符号链接为false 时复制元数据。现在返回dst。
版本3.2中已更改:添加了copy_function参数以便能够提供自定义复制功能。当符号链接为false 时,将ignore_dangling_symlinks参数添加到silent dangling符号链接错误中。
shutil.
rmtree
(path,ignore_errors = False,onerror = None )-
删除整个目录树; path必须指向目录(但不是指向目录的符号链接)。如果ignore_errors为true,则将忽略由删除失败导致的错误; 如果为false或省略,则通过调用onerror指定的处理程序来处理此类错误,或者,如果省略,则会引发异常。
注意
在支持必要的基于fd的功能的平台上,
rmtree()
默认情况下使用符号链接攻击抗性版本。在其他平台上,rmtree()
实现容易受到符号链接攻击:在适当的时间和环境下,攻击者可以操纵文件系统上的符号链接来删除他们无法访问的文件。应用程序可以使用rmtree.avoids_symlink_attacks
function属性来确定应用哪种情况。如果提供了onerror,则它必须是可调用的,它接受三个参数:function,path和excinfo。
第一个参数function是引发异常的函数; 这取决于平台和实施。第二个参数 path是传递给function的路径名。第三个参数 excinfo将是返回的异常信息
sys.exc_info()
。通过抛出的异常的onerror不会被抓住。版本3.3中已更改:添加了符号链接攻击抵抗版本,如果平台支持基于fd的功能,则会自动使用该版本。
rmtree.
avoids_symlink_attacks
- 指示当前平台和实现是否提供符号链接攻击的版本
rmtree()
。目前,这仅适用于支持基于fd的目录访问功能的平台。版本3.3中的新功能。
shutil.
move
(src,dst,copy_function = copy2 )- 递归地将文件或目录(src)移动到另一个位置(dst)并返回目标。
如果目标是现有目录,则src将在该目录中移动。如果目标已存在但不是目录,则可能会根据
os.rename()
语义覆盖目标。如果目标位于当前文件系统上,则
os.rename()
使用该目标。否则,使用copy_function将src复制到dst,然后删除。在符号链接的情况下, 将在dst中创建指向src目标的新符号链接,并且将删除src。如果给出copy_function,它必须是一个可调用的,它接受两个参数 src和dst,如果 不能使用,它将用于将src复制到dest
os.rename()
。如果源是一个目录,copytree()
则调用它,传递它copy_function()
。默认的copy_function是copy2()
。使用copy()
作为 copy_function允许移动成功时,它不可能也复制元数据,在没有任何复制元数据的费用。版本3.3中已更改:为外部文件系统添加了显式符号链接处理,从而使其适应GNU的mv行为。现在返回dst。
版本3.5中已更改:添加了copy_function关键字参数。
shutil.
disk_usage
(路径)- 将有关给定路径的磁盘使用情况统计信息作为命名元组返回 ,其属性为total,used和free,它们是total,used和free space的总量,以字节为单位。在Windows上,路径必须是目录; 在Unix上,它可以是文件或目录。
版本3.3中的新功能。
可用性:Unix,Windows。
shutil.
chown
(path,user = None,group = None )- 更改给定路径的所有者用户和/或组。
user可以是系统用户名或uid; 同样适用于群体。至少需要一个参数。
另请参见
os.chown()
基础功能。可用性:Unix。
版本3.3中的新功能。
shutil.
which
(cmd,mode = os.F_OK | os.X_OK,path = None )- 返回可执行文件的路径,如果调用了给定的cmd,该文件将运行。如果没有调用cmd,则返回
None
。mode是传递给的权限掩码
os.access()
,默认情况下确定文件是否存在且可执行。如果未指定路径,
os.environ()
则使用结果,返回“PATH”值或后退os.defpath
。在Windows上,无论您是使用默认路径还是提供自己的路径,当前目录始终都会添加到路径中,这是命令shell在查找可执行文件时使用的行为。此外,在路径中查找 cmd时,将检查环境变量。例如,如果您调用,将搜索 以确定它应在路径 目录中查找。例如,在Windows上:
PATHEXT
shutil.which("python")
which()
PATHEXT
python.exe
>>> >>> shutil.which("python") 'C:\\Python33\\python.EXE'
版本3.3中的新功能。
copytree示例
这个例子是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
。
另一个使用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)
rmtree例子
此示例显示如何在Windows上删除某些文件的只读位设置的目录树。它使用onerror回调清除readonly位并重新尝试删除。任何后续故障都会传播。
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,格式[,ROOT_DIR [,base_dir [,冗长[,dry_run [,所有者[,组[,记录器] ] ] ] ] ] ] )- 创建存档文件(例如zip或tar)并返回其名称。
base_name是要创建的文件的名称,包括路径,减去任何特定于格式的扩展名。format是存档格式:“zip”(如果
zlib
模块可用),“tar”,“gztar”(如果zlib
模块可用),“bztar”(如果bz2
模块可用)或“xztar”(如果该lzma
模块可用)。root_dir是一个目录,它将成为存档的根目录; 例如,我们通常在创建存档之前将chdir转换为root_dir。
base_dir是我们开始归档的目录; 即base_dir将是归档中所有文件和目录的公共前缀。
root_dir和base_dir都默认为当前目录。
如果dry_run为true,则不会创建存档,但会将执行的操作记录到logger。
创建tar存档时使用所有者和组。默认情况下,使用当前所有者和组。
记录器必须是与之兼容的对象PEP 282,通常是一个实例
logging.Logger
。的详细参数是未使用和废弃。
shutil.
get_archive_formats
()- 返回支持的归档格式列表。返回序列的每个元素都是元组。
(name, description)
默认情况下
shutil
提供以下格式:- zip:ZIP文件(如果
zlib
模块可用)。 - tar:未压缩的tar文件。
- gztar:gzip’ed tar-file(如果
zlib
模块可用)。 - bztar:bzip2’ed tar-file(如果该
bz2
模块可用)。 - xztar:xz’ed tar-file(如果
lzma
模块可用)。
您可以使用注册新格式或为任何现有格式提供自己的存档
register_archive_format()
。 - zip:ZIP文件(如果
shutil.
register_archive_format
(名称,功能[,extra_args [,description ] ] )- 注册格式名称的归档程序。
function是用于解压缩档案的可调用函数。callable将接收要创建的文件的base_name,然后是 base_dir(默认为
os.curdir
)以开始归档。进一步的参数作为关键字参数传递:owner,group, dry_run和logger(传入make_archive()
)。如果给定,extra_args是一对对的序列,当使用archiver callable时,它将用作额外的关键字参数。
(name,value)
使用description来
get_archive_formats()
返回归档器列表。默认为空字符串。
shutil.
unregister_archive_format
(名字)- 从支持的格式列表中删除存档格式名称。
shutil.
unpack_archive
(filename [,extract_dir [,format ] ] )- 解压缩档案。filename是存档的完整路径。
extract_dir是解压缩存档的目标目录的名称。如果未提供,则使用当前工作目录。
format是存档格式:“zip”,“tar”,“gztar”,“bztar”或“xztar”之一。或者注册的任何其他格式
register_unpack_format()
。如果未提供,unpack_archive()
将使用存档文件扩展名,并查看是否为该扩展注册了解包器。如果没有找到,ValueError
则引发a。改变在3.7版本:接受一个路径状物体的文件名和EXTRACT_DIR。
shutil.
register_unpack_format
(名称,扩展,功能[,extra_args [,description ] ] )- 注册解包格式。name是格式的名称,而 扩展名是与格式相对应的扩展名列表,例如
.zip
Zip文件。function是用于解压缩档案的可调用函数。callable将接收归档的路径,然后是必须提取归档的目录。
提供时,extra_args是一系列元组,它们将作为关键字参数传递给callable。
(name, value)
描述可被提供来描述的格式,并且将被返还
get_unpack_formats()
的功能。
shutil.
unregister_unpack_format
(名字)- 取消注册解压缩格式。name是格式的名称。
shutil.
get_unpack_formats
()- 返回所有已注册格式的列表以进行解包。返回序列的每个元素都是元组 。
(name, extensions, description)
默认情况下
shutil
提供以下格式:- zip:ZIP文件(解压缩压缩文件仅在相应模块可用时才有效)。
- tar:未压缩的tar文件。
- gztar:gzip’ed tar-file(如果
zlib
模块可用)。 - bztar:bzip2’ed tar-file(如果该
bz2
模块可用)。 - xztar:xz’ed tar-file(如果
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
查询输出终端的大小
shutil.
get_terminal_size
(fallback =(列,行))- 获取终端窗口的大小。
对于每个两个维度,该环境变量中,
COLUMNS
并LINES
分别被检查。如果定义了变量并且值是正整数,则使用它。当定义
COLUMNS
或LINES
未定义时,这是常见情况,sys.__stdout__
通过调用查询连接到的终端os.get_terminal_size()
。如果无法成功查询终端大小,或者因为系统不支持查询,或者因为我们未连接到终端,
fallback
则使用参数中给出的值。fallback
默认值是许多终端仿真程序使用的默认大小。(80, 24)
返回的值是类型的命名元组
os.terminal_size
。另请参见:Single UNIX Specification,Version 2, Other Environment Variables。
版本3.3中的新功能。