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.*'))
shutil_copyfile.py

运行效果

[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)
shutil_copyfileobj.py

 运行效果

默认:
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/*'))
shutil_copy.py

运行效果

[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')
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))
shutil_copymode.py

运行效果

[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')
shutil_copystat.py

运行效果

[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/*'))
shutil_copytree.py

运行效果

[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/*'))
shutil_copytree_verbose.py

运行效果

[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/*'))
shutil_rmtree.py

运行效果

[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*'))
shutil_move.py

运行效果

[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'))
shutil_which.py

运行效果

[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)
shutil_which_regular_file.py

运行效果

[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))
shutil_get_archive_formats.py

运行效果

[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)
shutil_make_archive.py

运行效果

[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))
shutil_get_unpack_formats.py

运行效果

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)
shutil_unpack_archive.py

运行效果

[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))
shutil_disk_usage.py

 

 运行效果

[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

posted @ 2020-04-30 15:09  小粉优化大师  阅读(517)  评论(0编辑  收藏  举报