Python shutil库高级文件操作指南:复制、归档与权限管理
本文深入解析Python标准库shutil的高级文件操作功能。涵盖copyfile、copy2等文件复制函数的区别,详解copytree在文件夹递归复制中的应用及过滤机制。同时介绍文件权限复制、目录移动、文件查找以及归档压缩与解压操作,并结合disk_usage进行磁盘空间检查,提供完整的代码示例与注意事项。
前言
什么是高层级的文件操作?
常规的文件操作通常局限于创建文件、新建文件夹以及向文件中写入数据。若需将文件内容复制至另一文件,使用pathlib等库往往需要手动执行打开源文件、读取内容、再写入目标文件的繁琐步骤。这种基础复制方式无形中增加了代码复杂度与操作步骤。
相比之下,shutil库能够直接完成文件间的复制操作,并支持归档处理。本文将详细介绍文件的高层次操作方法。
一、copyfile()函数
copyfile()函数用于将源文件的内容复制到目标文件中。准确而言,该函数并非仅复制内容,而是直接复制整个文件对象并允许指定新文件名。
具体示例如下:
import shutil
shutil.copyfile('week.csv', 'week_copy.csv')
代码仅有一行,第一个参数指定源文件路径,第二个参数指定目标文件路径。执行后效果如下:

二、copy()与copy2()函数
然而,copyfile()函数存在局限性,其原理是通过打开源文件进行读取。因此,对于某些特殊类型的文件(如UNIX设备节点),若缺乏相应权限,程序将抛出IOERROR错误。
此外,通过copyfile()复制生成的文件是一个新文件,它不包含原文件的访问时间与修改时间属性。
而copy2()函数在复制文件内容后,会同时保留原文件的访问时间与修改时间。具体示例如下:
import shutil
import os
import time
shutil.copy2('week.csv', 'week_copy.csv')
stat_info1 = os.stat('week.csv')
stat_info2 = os.stat('week_copy.csv')
print("源文件信息")
print(oct(stat_info1.st_mode))
print('文件创建时间:{}'.format(time.ctime(stat_info1.st_ctime)))
print('文件访问时间:{}'.format(time.ctime(stat_info1.st_atime)))
print('文件修改时间:{}'.format(time.ctime(stat_info1.st_mtime)))
print("复制文件信息")
print(oct(stat_info2.st_mode))
print('文件创建时间:{}'.format(time.ctime(stat_info2.st_ctime)))
print('文件访问时间:{}'.format(time.ctime(stat_info2.st_atime)))
print('文件修改时间:{}'.format(time.ctime(stat_info2.st_mtime)))
执行后效果如下:

copy()函数与copyfile()类似,均用于复制文件,但copy()更灵活,既支持文件也支持目录。若传入文件夹名称,它会将文件复制到该文件夹下,并保持原文件名;若传入文件夹路径给copyfile(),则会直接报错。
具体示例如下:
import shutil
import os
os.mkdir('data')
shutil.copy('week.csv', 'data')
执行后效果如下:

三、copymode()与copystat()函数
通过copy2()函数,我们了解了如何复制文件内容及时间信息。但该操作并不包含文件权限设置。例如在Win10系统中,C盘部分文件可能仅具备只读权限。若需将源文件的权限也复制到目标文件,该如何操作?
答案是使用copymode()函数,具体示例如下:
import shutil
import os, stat
with open("temp.txt", 'wt') as file:
file.write("11111111111111111")
os.chmod("temp.txt", stat.S_IREAD)
shutil.copymode('temp_copymode.txt', 'temp.txt')
print(oct(os.stat('temp.txt').st_mode))
print(oct(os.stat('temp_copymode.txt').st_mode))
需注意,copymode()仅复制文件权限属性,而非文件内容。这意味着目标文件名必须已存在,才能将源文件的权限赋予它。例如,此处是将temp.txt的权限复制给temp_copymode.txt,因此temp_copymode.txt必须预先存在。此操作仅改变权限,不复制文件内容(stat.S_IXGRP表示组用户组的执行权限)。
至于copystat()函数,它不仅复制文件权限,还复制文件的其他元信息。具体代码如下:
import shutil
import os, stat
import time
with open("temp.txt", 'wt') as file:
file.write("11111111111111111")
os.chmod("temp.txt", stat.S_IXGRP)
shutil.copystat('temp_copymode.txt', 'temp.txt')
stat_info1 = os.stat('temp.txt')
stat_info2 = os.stat('temp_copymode.txt')
print("源文件信息")
print(oct(stat_info1.st_mode))
print('文件创建时间:{}'.format(time.ctime(stat_info1.st_ctime)))
print('文件访问时间:{}'.format(time.ctime(stat_info1.st_atime)))
print('文件修改时间:{}'.format(time.ctime(stat_info1.st_mtime)))
print("复制文件信息")
print(oct(stat_info2.st_mode))
print('文件创建时间:{}'.format(time.ctime(stat_info2.st_ctime)))
print('文件访问时间:{}'.format(time.ctime(stat_info2.st_atime)))
print('文件修改时间:{}'.format(time.ctime(stat_info2.st_mtime)))
执行后效果如下:

四、复制整个文件夹
上述复制操作均针对单个文件。在实际项目中,常需将整个文件夹复制到指定位置。虽然实现文件夹递归复制涉及复杂逻辑,但shutil库提供了更简便的函数:copytree()。
具体示例如下:
import shutil
shutil.copytree('./text', './text_copy')
仅需一行代码即可完成整个文件夹的复制。需注意,第二个参数指定目标目录,该目录不能预先存在,copytree()会自动创建;若目标目录已存在,程序将报错。
参数copy_function
有时,我们复制文件夹时并不需要完整复制所有内容,而是希望筛选符合特定规则的文件。例如,仅复制某文件夹下所有后缀为.py的文件,如何实现?
具体示例如下:
import shutil
def verbose_copy(src, dst):
if src.endswith(".py"):
return shutil.copy2(src, dst)
shutil.copytree('./text', './text_copy', copy_function=verbose_copy)
此处通过copytree()函数的copy_function参数进行筛选。该参数接收一个函数,用于判断文件是否符合规则(如判断后缀是否为.py)后再执行复制。虽然会保留目录结构,但仅复制符合后缀条件的.py文件。
参数ignore
copytree()除了copy_function参数外,还提供ignore参数,用于排除特定文件。例如,若需复制除.py后缀外的所有文件,可如下实现:
import shutil
shutil.copytree('./text', './text_copy', ignore=shutil.ignore_patterns('*.py'))
如此,符合*.py规则的文件将被排除,不会执行复制操作。
五、删除整个文件夹
既然支持复制整个文件夹,shutil库也提供了反向操作函数rmtree(),用于删除整个文件夹。
import shutil
shutil.rmtree('./text_copy')
执行后,即可删除之前复制的文件夹内容。
六、移动文件夹或文件
除复制外,实际项目中常需将文件或目录移动至其他位置。shutil库提供了move()函数用于实现文件或文件夹的移动操作。
具体示例如下:
import shutil
shutil.move('week.csv', './text')
此处将csv文件移动至之前用于复制的text源文件目录中(移动文件夹的操作方式相同,仅需将文件名替换为文件夹名即可)。
七、查找文件
在更多文件操作场景中,往往需要查找特定文件。shutil库提供了which()函数用于搜索目标文件。该函数包含3个参数:mode用于设置查找文件的权限,path指定查找路径,cmd指定要查找的文件名。
具体示例如下:
import shutil
filename = shutil.which('python')
print(filename)
执行后效果如下:

八、归档操作
shutil库提供了更多高层函数来创建和解压归档文件。首先查看shutil库支持哪些压缩格式,具体示例如下:
import shutil
for format,desc in shutil.get_archive_formats():
print('{:<5}:{}'.format(format,desc))
执行后效果如下:

这简单理解为支持的压缩格式列表。
8.1 压缩文件
先来看一个简单的例子,将某个文件夹进行压缩,代码如下:
import shutil
shutil.make_archive('text','gztar',root_dir='..',base_dir='base_demo')
此处将text文件夹压缩为gztar格式。执行后效果如下:

其中,root_dir指定压缩路径的根目录(默认为当前目录),仅能指定路径,优先级低于base_dir。base_dir指定要压缩的文件或路径,可指定路径下的具体文件名或整个路径。
8.2 解压缩
既然有压缩,自然也有解压缩。shutil库提供了unpack_archive()函数用于解压文件。具体示例如下:
import shutil
shutil.unpack_archive('text.tar.gz',extract_dir='text_un')
unpack_archive()函数的第一个参数指定需要解压的文件,第二个参数指定解压后的目标目录。
8.3 文件系统空间
在执行可能耗尽可用空间的长时间操作前,最好先检查本地文件系统,查看剩余空间。shutil库提供了disk_usage()函数,返回总空间、已使用空间及未使用空间的信息。
具体示例如下:
import shutil
(total, used, free) = shutil.disk_usage("E:/")
BytesPerGB = 1024 * 1024 * 1024
print ("Total: %.2fGB" % (float(total)/BytesPerGB))
print ("Used: %.2fGB" % (float(used)/BytesPerGB))
print ("Free: %.2fGB" % (float(free)/BytesPerGB))
执行后效果如下:

此处博主获取了电脑E盘的信息,结果显示E盘总大小total为238G,已使用Used为43G,未使用Free为194G。一个健壮的程序必然严谨,因此在操作文件时,特别是处理大文件时,务必先判断磁盘大小再执行操作。
到此这篇关于Python高级文件操作之shutil库详解的文章就介绍到这了,更多相关Python shutil库内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









