shutil初识
shutil模块提供了大量关于文件和文件集合(表示一组文件)的高级操作,其中包括了提供支持文件复制和删除的功能。
目录和文件操作
使用shutil.copyfileobj(fsrc, fdst[, length]),将类文件对象fsrc的文件内容复制到类文件对象fdst中,可选参数length表示缓冲区大小。如果length被指定为负数,指的是不在数据块中循环源数据的情况下复制源数据,即不依赖数据块缓冲区。默认情况下,数据分块读取,以避免不受控制的内存消耗。需要注意的是,如果fsrc对象的当前位置不是0,则仅复制从当前文件位置到文件末尾的内容。
使用shutil.copyfile(src, dst, *, follow_symlinks=True),src和dst是以字符串形式给出的文件路劲名。将src文件的内容复制给dst文件,不复制元数据,返回dst。其中,dst必须是完整的文件目录名。如果src和dst指定的文件名相同,则会抛出shutil.SameFileError异常。目标位置必须是可写的,否则会抛出OsError异常。如果dst存在,则覆盖。这个函数无法复制特殊文件(字符设备,块设备,管道等)。如果follow_symlinks为False且src为符号链接,则将创建一个新的符号链接,而不是复制src符号链接指向的文件
使用shutil.copymode(src, dst, *, follow_symlinks=True),src和dst是以字符串形式给出的文件路劲。拷贝src的权限位给dst,dst的文件内容,所有者和所有组不受影响。如果follow_symlinks=False,并且src和dst都是符号链接,copymode()将尝试修改dst符号链接本身的模式,而不是修改dst指向的文件。并不是每个平台都提供此功能(对符号链接文件进行操作)。如果被强制要求在不支持该功能的平台上使用该函数,它将不执行任何操作并返回
使用shutil.copystat(src, dst, *, follow_symlinks=True),src和dst是以字符串形式给出的文件路劲。除了文件内容,所有者和所有组不拷贝,其他文件元信息都拷贝。如果follow_symlinks=False,并且src和dst都是符号链接,则copystat()将对符号链接文件本身进行操作
值得注意的是,并非所有平台都提供检查和修改符号链接的功能。我们可以通过python在本地可以用哪些功能:
1.如果os.chmod in os.supports_follow_links为True,copystat()可以修改符号链接的权限位
2.如果os.utime in os.supports_follow_links为True,copystat()可以修改符号链接的上次访问和修改时间
3.如果os.chflags in os.supports_follow_links为True,copystat()可以修改符号链接的标志(注意:os.chflags并非在所有平台上都有效)
综述,在某些或所有功能都不可用的平台上,当要求修改符号链接时,copystat()将复制它可以复制的所有内容。
copystat()永远不会返回失败!
使用shutil.copy(src, dst, *, follow_symlinks=True),src和dst应该是文件路劲字符串,如果dst是一个目录,则将会在dst目录中生成一个和src基本文件名一样的文件,返回新创建文件的路劲。如果follow_symlinks=False,并且src是一个符号链接,dst被创建为一个符号链接。如果follow_symlinks=True,,并且src是一个符号链接,dst将是src指向的文件的副本。copy()只拷贝文件数据和文件权限模式。其他的元数据(如文件的创建和修改时间)不保留。想要保留原始文件的所有文件元数据,你应该使用copy2。(但这也不能复制所有,在posix系统上不能复制文件的所有者和所有组,总之不要轻易相信它们!)
使用shutil.copy2(src, dst, *, follow_symlinks=True),和copy相同,copy2也尝试保留文件的元数据。当follow_symlinks为False,并且src为符号链接时,copy2()会尝试将所有元数据从src符号链接复制到新创建的dst符号链接,这种功能,不是所有平台都会提供! 在某些或所有此功能不可用的平台上,copy2()将保留它可以保留的所有元数据。copy2()永远不会返回失败!因为copy2使用copystat()去拷贝文件元数据
使用shutil.ignore_patterns(*patterns),这个函数是专门为copytree服务的,使用该函数创建一个函数,该函数可用作copytree()的ignore参数的可调用函数,利用glob风格的模式忽略相关文件和目录
使用shutil.copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False),递归复制以src为根的整个目录树,返回目标目录。由dst命名的目标目录必须不存在。如果symlinks为True,则源目录树中的符号链接将表示为新目录树中的符号链接(即源目录树中的符号链接指向新目录中的符号链接),并且将在平台允许的范围内复制原始链接的元数据 。如果symlinks为False或者忽略不写,源目录树中的符号链接的内容和元数据将复制到新目录树中。当symlinks为False时,如果symlink指向的文件不存在,复制过程结束时将出现异常 ,如果要抑制这个异常,可以将ignore_dangling_symlinks设置为true。注意,此选项对不支持os.symlink()的平台没有影响。如果给定ignore,则它必须是一个可调用函数,它将接收copytree()访问的目录下的内容列表作为其参数,由于copytree()是递归调用的,因此将为复制的每个目录调用一次ignore函数。这个ignore函数必须返回相对于dst目录的 目录名和文件名序列。这些名称将在复制过程中被忽略。用copy_function去复制每个文件。自定义ignore函数必须满足ignore_func(path,names),其中path代表当前遍历的目录,names是个列表,os.listdir(path)
from shutil import copytree,ignore_pattern
copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))
使用shutil.rmtree(path, ignore_errors=False, onerror=None),删除整个目录树。path必须指向目录(但不是指向目录的符号链接)。如果ignore_errors为True,则将忽略由于删除失败而导致的错误。如果ignore_errors为False,则通过调用onerror指定的错误处理程序来处理此类错误,如果onerror=None,则会引发异常 。rmtree容易引发攻击,因为它可以通过删除符号链接来删除本没有权限访问的文件。如果要防止这种攻击,要看shutil.rmtree.avoids_symlink_attacks是否为True,指示当前操作系统是否提供了抗攻击的rmtree版本
其中onerror函数必须接受三个参数function(引发异常的函数)、path和excinfo(sys.exc_info()返回的异常信息 ),这个函数引发的异常不会被捕获。
使用shutil.move(src, dst, copy_function=copy2),递归地将文件或目录(src)移动到另一个位置(dst),并返回dst。如果dst目录存在,则将src移动到该目录中,如果dst文件存在,则不同的平台有不同的表现,可能会覆盖。如果dst位于当前目录上,则行为是os.rename()。否则,使用copy_function先复制,然后删除src。当os.rename()不能用时候,会用copy_function。如果src是目录,copytree()将被调用,并把copy_function传递给copytree()。如果copy_function被指定为copy,可以在不可能同时复制元数据和数据的情况下进行成功移动,但代价是不复制任何元数据。
使用shutil.disk_usage(path),返回一个命名元组,这个命名元组记录了给定path的磁盘使用情况统计,属性total,used,free以字节为单位。在Windows上,path必须是目录。而Unix既可以是目录也可以是文件
使用shutil.chown(path, user=None, group=None),user可以传系统用户名或uid ,group与user相同。
使用shutil.which(cmd, mode=os.F_OK | os.X_OK, path=None),cmd必须是以os.environ['PATHEXT']为后缀名。如果不调用cmd,则返回None。mode传递给操作系统,默认存在且可执行。如果不指定path,函数内部默认搜索os.environ()。在Windows上,无论你是否使用默认目录或提供自己的目录,当前目录始终位于路劲的前面,这是shell在查找可执行文件时使用的行为。
一个在多文件操作时引发的异常shutil.Error
压缩文件操作
shutil的文件归档操作依赖于模块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模块可用)、"tar"、"gztar"(如果zlib模块可用)、"bztar"(如果bz2模块可用)或"xztar"(如果lzma模块可用)。root_dir是一个目录,它将成为归档文件的根目录,归档文件中的所有路劲都将与其有关,我们通常在创建归档文件之前先进入到根目录。base_dir是我们开始归档的目录,base_dir将是存档中所有文件和目录的前缀,base_dir必须相对于根目录指定。base_dir和root_dir都默认为当前目录。如果dry_run为True,则不会创建存档,但将执行的操作会记录到logger,owner和group指定创建tar存档的所有者和所有组,默认情况下,使用当前所有者和组。verbose参数被废弃了。logger通常是logging.Logger的实例
shutil.get_archive_formats(),返回支持的存档格式列表,这个列表的每个元素是一个元组(名字,描述),你可以通过register_archive_formats()注册新格式
shutil.register_archive_format(name, function[, extra_args[, description]])¶,为格式名称注册归档程序,function用于压缩归档文件,function有两个参数,base_name,base_dir,其他的参数作为关键字参数传递,owner, group,dry_run和logger。description默认是 一个空字符串,由get_archive_formats()返回。如果给extra_args参数,它是一个(name,value)序列
shutil.unregister_archive_format(name),从支持的格式列表中删除存档格式名称
shutil.unpack_archive(filename[, extract_dir[, format]]) 解压文档,filename是归档文件的完整路径,extract_dir是解压缩归档文件的目标目录的名称,默认是当前工作目录。格式是存档格式:“zip”、“tar”、“gztar”、“bztar”或“xztar”之一或是使用register_unpack_format()注册的任何其他格式。如果未提供,unpack_archive()将使用存档文件扩展名,并查看是否为该扩展名注册了解包程序。如果未找到,则会引发ValueError。
shutil.register_unpack_format(name, extensions, function[, extra_args[, description]]),注册解包格式,name是格式名称,extensions是扩展名,function用于打开归档文件,参数1:归档文件的路劲,参数2:归档文件提取到的目录。description提供给get_unpack_formats()。
shutil.unregister_unpack_format(name),取消注册解包格式,name是格式的名称
查询输出终端的大小
shutil.get_terminal_size(fallback=(columns, lines)),获取终端窗口的大小。这有什么用呢?(开个玩笑,对于脚本来说,给程序员看是很有用的)。应该这样调用shutil.get_terminal_size(COLUMNS,LINES)获取
综述
以上是我对shutil的总结,几乎涵盖了shutil的所有用法, 写这个的原因是为了结合pathlib一起使用。如要转载,请标明转载地址和作者。相信你懂了这两个模块,任何文件操作都能得心应手了! 哈哈........
作者:翔宇哥