FreezeJ' Blog

python shutil 高阶文件操作

2021-03-31

shutil 模块提供了一系列对文件和文件集合的高阶操作。 特别是提供了一些支持文件拷贝和删除的函数。 对于单个文件的操作,请参阅 os 模块。
官方文档:https://docs.python.org/zh-cn/3.6/library/shutil.html

复制文件

目标位置必须是可写的;否则将引发 OSError 异常。 如果 dst 已经存在,它将被替换。 特殊文件如字符或块设备以及管道无法用此函数来拷贝。

import shutil
shutil.copyfile(src='shutil_source.txt', dst='shutil_copyfile.txt')  # 不含元数据和mode
shutil.copy(src='shutil_source.txt', dst='shutil_copy.txt')  # 不含元数据,包含mode
shutil.copy2(src='shutil_source.txt', dst='shutil_copy2.txt')  # 包含元数据和mode
# shutil.copyfileobj用于拷贝文件对象

输出结果:

stat shutil_*
  File: `shutil_copy2.txt'
  Size: 4               Blocks: 8          IO Block: 4096   regular file
Device: fc02h/64514d    Inode: 531612      Links: 1
Access: (0700/-rwx------)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2021-03-31 10:33:11.291741001 +0800
Modify: 2021-01-15 11:05:03.362159953 +0800
Change: 2021-03-31 10:33:11.292741001 +0800
  File: `shutil_copyfile.txt'
  Size: 4               Blocks: 8          IO Block: 4096   regular file
Device: fc02h/64514d    Inode: 531610      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2021-03-31 10:30:52.818741001 +0800
Modify: 2021-03-31 10:33:11.291741001 +0800
Change: 2021-03-31 10:33:11.291741001 +0800
  File: `shutil_copy.txt'
  Size: 4               Blocks: 8          IO Block: 4096   regular file
Device: fc02h/64514d    Inode: 531611      Links: 1
Access: (0700/-rwx------)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2021-03-31 10:30:52.819741001 +0800
Modify: 2021-03-31 10:33:11.291741001 +0800
Change: 2021-03-31 10:33:11.291741001 +0800
  File: `shutil_source.txt'
  Size: 4               Blocks: 8          IO Block: 4096   regular file
Device: fc02h/64514d    Inode: 530848      Links: 1
Access: (0700/-rwx------)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2021-03-31 10:33:11.291741001 +0800
Modify: 2021-01-15 11:05:03.362159953 +0800
Change: 2021-03-31 10:31:59.181741001 +0800

目录递归操作

import shutil
shutil.copytree(src='./test', dst='./test_copy', copy_function=shutil.copy2,ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))  # 递归复制目录,copy_function指定复制的方法,ignore指定忽略正则
shutil.rmtree(path='./test_copy', ignore_errors=True)  # 递归复制目录,ignore_errors为真忽略删除错误

移动目录

递归地将一个文件或目录 (src) 移至另一位置 (dst) 并返回目标位置。
如果目标是已存在的目录,则 src 会被移至该目录下。 如果目标已存在但不是目录,它可能会被覆盖。
注意:如果目标是在当前文件系统中,则会使用 os.rename()。 在其他情况下,src 将被拷贝至 dst,使用的函数为 copy_function,然后目标会被移除。

import shutil
shutil.move(src='./test', dst='./test_copy', copy_function=shutil.copy2)

归档

import shutil
shutil.get_archive_formats()  # 返回支持的归档格式列表。
# 输出:[('bztar', "bzip2'ed tar-file"), ('gztar', "gzip'ed tar-file"), ('tar', 'uncompressed tar file'), ('zip', 'ZIP file')]

# 创建一个归档文件
shutil.make_archive(
    base_name='test',
    format='gztar',
    root_dir='/tmp/',  # 操作根目录,默认当前目录
)

# 解压归档文件
shutil.unpack_archive(
    filename='/tmp/test.tar.gz',  # 解压文件绝对路径
    extract_dir='/tmp/tar_test/',  # 解压到哪个目录
    format='gztar'  # 不提供会自动根据后缀识别
)

其它

import shutil
# 从src拷贝权限位、最近访问时间、最近修改时间以及旗标到dst
shutil.copystat(src, dst)

# 从src拷贝权限位到dst。 文件的内容、所有者和分组将不受影响。
shutil.copymode(src, dst)

# 改变路径属主和属组(不会递归)
shutil.chown('test', user='mysql', group='nginx')  # drwxr-xr-x 3 mysql nginx 4096 Mar 31 11:09 

# 统计占用空间
shutil.disk_usage('/tmp')  # usage(total=51471126528, used=12239486976, free=36610199552)

# 列出命令执行的绝对路径
shutil.which('ls')  # /bin/ls

# 查询输出终端的尺寸
shutil.get_terminal_size()  # os.terminal_size(columns=138, lines=32)
Tags: Python