Python之shutil模块的使用
shutil模块的作用
主要用于文件或目录的复制或归档的操作
1、复制文件,如果没有权限的话,会抛出IOError异常
import shutil import glob print('之前的目录',glob.glob('shutil_copyfile.*')) shutil.copyfile('shutil_copyfile.py','shutil_copyfile.py.copy') print('之后的目录',glob.glob('shutil_copyfile.*'))
运行效果
[root@python-mysql opt]# python3 shutil_copyfile.py 之前的目录 ['shutil_copyfile.py'] 之后的目录 ['shutil_copyfile.py', 'shutil_copyfile.py.copy']
2、复制内存的数据,copyfileobj()
import shutil import io class VerboseStringIO(io.StringIO): def read(self, n=-1): next = io.StringIO.read(self, n) print('read({}) got {} bytes'.format(n, len(next))) return next lorem_ipsum = '''Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vestibulum aliquam mollis dolor. Donec vulputate nunc ut diam. Ut rutrum mi vel sem. Vestibulum ante ipsum.''' print('默认:') input = VerboseStringIO(lorem_ipsum) output = io.StringIO() shutil.copyfileobj(input, output) print('') print('一次性复制 到 StringIO:') input = VerboseStringIO(lorem_ipsum) output = io.StringIO() shutil.copyfileobj(input, output, -1) print('') print('一次复制256块 到 StringIO:') input = VerboseStringIO(lorem_ipsum) output = io.StringIO() shutil.copyfileobj(input, output, 256)
运行效果
默认: read(16384) got 166 bytes read(16384) got 0 bytes 一次性复制 到 StringIO: read(-1) got 166 bytes read(-1) got 0 bytes 一次复制256块 到 StringIO: read(256) got 166 bytes read(256) got 0 bytes
注意:其实copyfile(),底层函数的实现就是copyfileobj()
3、复制文件的权限和文件的内容copy()
import glob import os import shutil os.mkdir('example') print('之前的目录', glob.glob('example/*')) shutil.copy('shutil_copy.py', 'example') print('之后的目录', glob.glob('example/*'))
运行效果
[root@python-mysql opt]# python3 shutil_copy.py 之前的目录 [] 之后的目录 ['example/shutil_copy.py']
4、复制文件的权限和文件的内容copy2(),对文件的访问时间 、修改时间、创建时间不做修改的复制
import os import shutil def show_file_info(filename): stat_info = os.stat(filename) print('权限', oct(stat_info.st_mode)) print('创建时间', stat_info.st_ctime) print('访问时间', stat_info.st_atime) print('修改时间', stat_info.st_mtime) os.mkdir('example') print('源文件') show_file_info('shutil_copy2.py') shutil.copy2('shutil_copy2.py', 'example') show_file_info('example/shutil_copy2.py')
运行效果
[root@python-mysql opt]# python3 shutil_copy2.py 源文件 权限 0o100644 创建时间 1588125882.0550265 访问时间 1588125892.1534145 修改时间 1588125882.0540266 权限 0o100644 创建时间 1588125892.1724114 访问时间 1588125892.1534145 修改时间 1588125882.0540266
5、将一个文件的权限(即数据源 ),附值到指定的文件上,copymode()
import shutil import os with open('file_to_change.txt', 'wt') as wf: wf.write('Content') os.chmod('file_to_change.txt', 0o444) print('没有修改之前:', oct(os.stat('file_to_change.txt').st_mode)) shutil.copymode('shutil_copymode.py', 'file_to_change.txt') print('修改之后:', oct(os.stat('file_to_change.txt').st_mode))
运行效果
[root@python-mysql opt]# python3 shutil_copymode.py 没有修改之前: 0o100444 修改之后: 0o100644
6、复制文件的权限和修改日期 、创建日期、访问日期
import os import shutil import time def show_file_info(filename): stat_info = os.stat(filename) print('权限', oct(stat_info.st_mode)) print('创建时间', time.ctime(stat_info.st_ctime)) print('访问时间', time.ctime(stat_info.st_atime)) print('修改时间', time.ctime(stat_info.st_mtime)) with open('file_to_change.txt', 'wt') as f: f.write('Content') os.chmod('file_to_change.txt', 0o444) print('没有修改之前') show_file_info('file_to_change.txt') shutil.copystat('shutil_copystat.py', 'file_to_change.txt') print('修改之后') show_file_info('file_to_change.txt')
运行效果
[root@python-mysql opt]# python3 shutil_copystat.py 没有修改之前 权限 0o100444 创建时间 Wed Apr 29 10:59:45 2020 访问时间 Wed Apr 29 10:19:04 2020 修改时间 Wed Apr 29 10:59:45 2020 修改之后 权限 0o100644 创建时间 Wed Apr 29 10:59:45 2020 访问时间 Wed Apr 29 10:59:45 2020 修改时间 Wed Apr 29 10:58:35 2020
7、复制目录数据,目标目录必须是不存在
import glob import pprint import shutil print('没有复制目录前') pprint.pprint(glob.glob('/tmp/example/*')) shutil.copytree('./example', '/tmp/example') print('复制目录后') pprint.pprint(glob.glob('/tmp/example/*'))
运行效果
[root@python-mysql opt]# python3 shutil_copytree.py 没有复制目录前 [] 复制目录后 ['/tmp/example/shutil_copy2.py', '/tmp/example/file_to_change.txt', '/tmp/example/test.jar', '/tmp/example/shutil_copystat.py']
8、过滤不需要的文件名,复制目录
import glob import pprint import shutil def verbose_copy(src, dst): print('复制 {} 到 {}'.format(src, dst)) return shutil.copy2(src, dst) print('没有复制目录前') pprint.pprint(glob.glob('/tmp/example/*')) shutil.copytree('./example', '/tmp/example', copy_function=verbose_copy, ignore=shutil.ignore_patterns('*.jar'), ) print('复制目录后') pprint.pprint(glob.glob('/tmp/example/*'))
运行效果
[root@python-mysql opt]# python3 shutil_copytree_verbose.py 没有复制目录前 [] 复制 ./example/shutil_copy2.py 到 /tmp/example/shutil_copy2.py 复制 ./example/file_to_change.txt 到 /tmp/example/file_to_change.txt 复制 ./example/shutil_copystat.py 到 /tmp/example/shutil_copystat.py 复制目录后 ['/tmp/example/shutil_copy2.py', '/tmp/example/file_to_change.txt', '/tmp/example/shutil_copystat.py']
9、删除目录数据
import glob import pprint import shutil print('没有删除目录前') pprint.pprint(glob.glob('/tmp/example/*')) shutil.rmtree('/tmp/example') print('没有删除目录后') pprint.pprint(glob.glob('/tmp/example/*'))
运行效果
[root@python-mysql opt]# python3 shutil_rmtree.py 没有删除目录前 ['/tmp/example/shutil_copy2.py', '/tmp/example/file_to_change.txt', '/tmp/example/shutil_copystat.py'] 没有删除目录后 []
10、剪切文件
import glob import shutil with open('example.txt', 'wt') as wf: wf.write('Contents') print('没有剪切之前', glob.glob('example*')) shutil.move('example.txt', 'example.out') print('没有剪切之后', glob.glob('example*'))
运行效果
[root@python-mysql opt]# python3 shutil_move.py 没有剪切之前 ['example', 'example.txt'] 没有剪切之后 ['example', 'example.out']
11、在环境变量中,查询命令的位置,类型linux的which功能
import shutil print(shutil.which('virtualenv')) print(shutil.which('python')) print(shutil.which('tox'))
运行效果
[root@python-mysql opt]# python3 shutil_which.py None /bin/python None
12、增加环境变量,并且使用权限过滤,筛选出最终文件名
import shutil import os path = os.pathsep.join([ '.', os.path.expanduser('~/pymotw') ]) mode = os.F_OK | os.R_OK print(oct(mode)) filename = shutil.which( 'config.ini', mode=mode, path=path ) print(filename)
运行效果
[root@python-mysql opt]# python3 shutil_which_regular_file.py 0o4 /root/pymotw/config.ini
13、查询支持归档的格式
import shutil for format, descriptoin in shutil.get_archive_formats(): print('{:<5}:{}'.format(format, descriptoin))
运行效果
[root@python-mysql opt]# python3 shutil_get_archive_formats.py bztar:bzip2'ed tar-file gztar:gzip'ed tar-file tar :uncompressed tar file zip :ZIP file
14、多个文件,进行归档
import logging import shutil import sys import tarfile logging.basicConfig( format='%(message)s', stream=sys.stdout, level=logging.DEBUG ) logger = logging.getLogger('pymotw') print('创建归档') shutil.make_archive( base_name='example_file', format='gztar', root_dir='..', # 返回上层的目录 base_dir='example', logger=logger) print('查看归档的内容') with tarfile.open('example_file.tar.gz', 'r') as t: for n in t.getnames(): print(n)
运行效果
[root@python-mysql example]# python3 shutil_make_archive.py 创建归档 changing into '..' Creating tar archive changing back to '/opt/example' 查看归档的内容 example example/shutil_copy2.py example/file_to_change.txt example/test.jar example/shutil_copystat.py example/shutil_make_archive.py
15、查看解压归档的格式
import shutil for format, exts, description in shutil.get_unpack_formats(): print('{:<5}: {}, names ending in {}'.format(format, description, exts))
运行效果
bztar: bzip2'ed tar-file, names ending in ['.tar.bz2', '.tbz2'] gztar: gzip'ed tar-file, names ending in ['.tar.gz', '.tgz'] tar : uncompressed tar file, names ending in ['.tar'] xztar: xz'ed tar-file, names ending in ['.tar.xz', '.txz'] zip : ZIP file, names ending in ['.zip']
16、解压归档
import pathlib import shutil import sys import tempfile with tempfile.TemporaryDirectory() as d: print('解压归档:') shutil.unpack_archive( 'example_file.tar.gz', extract_dir=d ) print('创建:') for extracted in pathlib.Path(d).rglob('*'): print(extracted)
运行效果
[root@python-mysql opt]# python3 shutil_which_regular_file.py 解压归档: 创建: /tmp/tmp_s520lfu/example /tmp/tmp_s520lfu/example/shutil_copy2.py /tmp/tmp_s520lfu/example/file_to_change.txt /tmp/tmp_s520lfu/example/test.jar /tmp/tmp_s520lfu/example/shutil_copystat.py /tmp/tmp_s520lfu/example/shutil_make_archive.py
17、查看当前文件系统的空间大小
import shutil total_b, used_b, free_b = shutil.disk_usage('.') gib = 2 ** 30 # GiB == gibibyte gb = 10 ** 9 # GB == gigabyte print('总的大小: {:6.2f} GB {:6.2f} GiB'.format(total_b / gb, total_b / gib)) print('已使用的大小 : {:6.2f} GB {:6.2f} GiB'.format(used_b / gb, used_b / gib)) print('未使用的大小 : {:6.2f} GB {:6.2f} GiB'.format(free_b / gb, free_b / gib))
运行效果
[root@python-mysql opt]# python3 shutil_disk_usage.py 总的大小: 18.24 GB 16.99 GiB 已使用的大小 : 8.58 GB 7.99 GiB 未使用的大小 : 9.66 GB 8.99 GiB
test