• python- shutil 高级文件操作


    简介

    shutil模块提供了大量的文件的高级操作。特别针对文件拷贝和删除,主要功能为目录和文件操作以及压缩操作。对单个文件的操作也可参见os模块。

    注意即便是更高级别的文件复制函数(shutil.copy(),shutil.copy2())也不能复制所有文件的元数据。这意味着在POSIX平台上,文件的所有者和组以及访问控制列表都将丢失。在Mac OS中资源fork和其他元数据无法使用。这意味着资源将丢失,文件类型和创建者代码将不正确。在Windows上,文件所有者,ACL和备用数据流不会被复制。

    • 功能:高级文件操作。
    • 类型:标准模块
    • 相关模块:
      1. os 标准模块。
      2. zipfile 标准模块。
      3. tarfile 标准模块。

    拷贝文件

    shutil.copyfile(src, dst):复制文件内容(不包含元数据)从src到dst。 DST必须是完整的目标文件名;拷贝目录参见shutil.copy()。如果src和dst是同一文件,就会引发错误shutil.Error。dst必须是可写的,否则将引发异常IOError。如果dst已经存在,它会被替换。特殊文件,例如字符或块设备和管道不能使用此功能,因为copyfile会打开并阅读文件。 src和dst的是字符串形式的路径名。

    from shutil import *
    from glob import glob
    
    print 'BEFORE:', glob('shutil_copyfile.*')
    copyfile('shutil_copyfile.py', 'shutil_copyfile.py.copy')
    print 'AFTER:', glob('shutil_copyfile.*')
    
    

    执行结果:

    # python shutil_copyfile.py
    BEFORE: ['shutil_copyfile.py']
    AFTER: ['shutil_copyfile.py', 'shutil_copyfile.py.copy']
    # python shutil_copyfile.py
    BEFORE: ['shutil_copyfile.py', 'shutil_copyfile.py.copy']	
    
    

    copyfile()调用了底函数层copyfileobj()。
    shutil.copyfileobj(fsrc, fdst[, length]):复制文件内容(不包含元数据)从类文件对象src到类文件对dst。可选参数length指定缓冲区的大小,负数表示一次性读入。默认会把数据切分成小块拷贝,以免占用太多内存。注意:拷贝是从fsrc的当前文件开始。

    from shutil import *
    import os
    from StringIO import StringIO
    import sys
    
    class VerboseStringIO(StringIO):
        def read(self, n=-1):
            next = StringIO.read(self, n)
            print 'read(%d) bytes' % n
            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 'Default:'
    input = VerboseStringIO(lorem_ipsum)
    output = StringIO()
    copyfileobj(input, output)
    
    print
    
    print 'All at once:'
    input = VerboseStringIO(lorem_ipsum)
    output = StringIO()
    copyfileobj(input, output, -1)
    
    print
    
    print 'Blocks of 256:'
    input = VerboseStringIO(lorem_ipsum)
    output = StringIO()
    copyfileobj(input, output, 256)
    
    

    执行结果:

    # python shutil_copyfileobj.py
    Default:
    read(16384) bytes
    read(16384) bytes
    
    All at once:
    read(-1) bytes
    read(-1) bytes
    
    Blocks of 256:
    read(256) bytes
    read(256) bytes
    

    shutil.copy(src, dst):复制文件src到文件或目录dst。如果dst是目录,使用src相同的文件名创建(或覆盖),权限位也会复制。src和dst的是字符串形式的路径名。

    from shutil import *
    import os
    
    os.mkdir('example')
    print 'BEFORE:', os.listdir('example')
    copy('shutil_copy.py', 'example')
    print 'AFTER:', os.listdir('example')
    

    执行结果:

    # python shutil_copy.py
    BEFORE: []
    AFTER: ['shutil_copy.py'
    
    

    shutil.copy2(src, dst):类似shutil.copy,元数据也复制,实际上先调用shutil.copy,然后使用copystat。这类似于Unix命令cp -p。

    from shutil import *
    import os
    import time
    
    def show_file_info(filename):
        stat_info = os.stat(filename)
        print '	Mode    :', stat_info.st_mode
        print '	Created :', time.ctime(stat_info.st_ctime)
        print '	Accessed:', time.ctime(stat_info.st_atime)
        print '	Modified:', time.ctime(stat_info.st_mtime)
    
    os.mkdir('example')
    print 'SOURCE:'
    show_file_info('shutil_copy2.py')
    copy2('shutil_copy2.py', 'example')
    print 'DEST:'
    show_file_info('example/shutil_copy2.py')
    
    

    执行结果:

    # python shutil_copy2.py
    SOURCE:
            Mode    : 33279
            Created : Fri Dec  6 10:45:52 2013
            Accessed: Fri Dec  6 11:49:40 2013
            Modified: Mon Feb 21 01:37:46 2011
    DEST:
            Mode    : 33279
            Created : Fri Dec  6 11:51:58 2013
            Accessed: Fri Dec  6 11:49:40 2013
            Modified: Mon Feb 21 01:37:46 2011
    
    

    shutil.ignore_patterns(*patterns) 为copytree的辅助函数,提供glob功能,示例:

    from shutil import copytree, ignore_patterns
    
    copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))
    
    

    拷贝文件元数据

    当由UNIX下创建文件默认基于umask设置权限,copymode()可以复制权限。

    shutil.copymode(src, dst):从SRC复制权限位到DST。该文件的内容,所有者和组不受影响。src和dst的是字符串形式的路径名。

    from shutil import *
    from commands import *
    import os
    
    with open('file_to_change.txt', 'wt') as f:
        f.write('content')
    os.chmod('file_to_change.txt', 0444)
    
    print 'BEFORE:'
    print getstatus('file_to_change.txt')
    copymode('shutil_copymode.py', 'file_to_change.txt')
    print 'AFTER :'
    print getstatus('file_to_change.txt')
    
    

    执行结果:

    # ./shutil_copymode.py 
    BEFORE:
    -r--r--r-- 1 root root 7 Dec  7 17:35 file_to_change.txt
    AFTER :
    -rwxrwxrwx 1 root root 7 Dec  7 17:35 file_to_change.txt
    
    

    要想拷贝文件时间戳,需要copystat。

    shutil.copystat(src, dst): 从src复制权限位,最后访问时间,最后修改时间,flag到dst。该文件的内容,所有者和组不受影响。 src和dst的是给定的字符串路径名。

    from shutil import *
    import os
    import time
    
    def show_file_info(filename):
        stat_info = os.stat(filename)
        print '	Mode    :', stat_info.st_mode
        print '	Created :', time.ctime(stat_info.st_ctime)
        print '	Accessed:', time.ctime(stat_info.st_atime)
        print '	Modified:', time.ctime(stat_info.st_mtime)
    
    with open('file_to_change.txt', 'wt') as f:
        f.write('content')
    os.chmod('file_to_change.txt', 0444)
    
    print 'BEFORE:'
    show_file_info('file_to_change.txt')
    copystat('shutil_copystat.py', 'file_to_change.txt')
    print 'AFTER:'
    show_file_info('file_to_change.txt')
    
    

    执行结果:

    # python shutil_copystat.py
    BEFORE:
            Mode    : 33060
            Created : Mon Dec  9 10:07:26 2013
            Accessed: Sat Dec  7 17:35:08 2013
            Modified: Mon Dec  9 10:07:26 2013
    AFTER:
            Mode    : 33279
            Created : Mon Dec  9 10:07:26 2013
            Accessed: Mon Dec  9 10:06:14 2013
            Modified: Mon Feb 21 01:37:46 2011
    
    

    压缩解压

    2.7以后的版本提供了压缩和解压功能。

    shutil.make_archive(base_name, format[, root_dir[, base_dir[, verbose[, dry_run[, owner[, group[, logger]]]]]]]):创建归档文件(如ZIP或TAR),返回其名字。base_name文件名。format压缩格式,“zip”, “tar”, “bztar” or “gztar”。root_dir压缩的根目录。base_dir开始压缩的目录。root_dir 和 base_dir默认都是当前目录。所有者和组默认为当前用户和组;logger为logging.Logger的实例。

    shutil.get_archive_formats():返回支持的格式列表。默认支持:

    • gztar:gzip压缩的tar文件
    • bztar:bzip2格式的tar文件
    • tar:未压缩的tar文件
    • zip:ZIP文件
    In [3]: shutil.get_archive_formats()
    Out[3]: 
    [('bztar', "bzip2'ed tar-file"),
     ('gztar', "gzip'ed tar-file"),
     ('tar', 'uncompressed tar file'),
     ('zip', 'ZIP file')]
    
    

    通过使用register_archive_format()可以增加新格式。

    shutil.register_archive_format(name, function[, extra_args[, description]]):注册一个文件格式。不常用。

    shutil.unregister_archive_format(name):移除文件格式,不常用。

    压缩实例:

    from shutil import make_archive
    import os
    archive_name = os.path.expanduser(os.path.join('~', 'myarchive'))
    root_dir = os.path.expanduser(os.path.join('~', '.ssh'))
    make_archive(archive_name, 'gztar', root_dir)
    
    

    上面代码会在当前用户目录生成压缩了.ssh目录的文件。

    # tar tzvf myarchive.tar.gz 
    dr-x------ root/root         0 2013-10-22 18:52 ./
    -rw------- root/root      1675 2013-06-06 20:01 ./id_rsa
    -rw-r--r-- root/root       392 2013-06-06 20:01 ./id_rsa.pub
    -r-------- root/root      1185 2013-08-06 09:41 ./authorized_k
    
  • 相关阅读:
    HDU 2147 找规律博弈
    HDU 1564 找规律博弈
    寒假训练3解题报告 CodeForces #148
    HDU 1525 Euclid Game
    状态压缩DP总结
    HDU 1079 简单博弈
    CodeForces 159E
    codeforces 88E Interesting Game
    【poj2891-Strange Way to Express Integers】拓展欧几里得-同余方程组
    【poj1006-biorhythms】中国剩余定理
  • 原文地址:https://www.cnblogs.com/dancesir/p/7909803.html
Copyright © 2020-2023  润新知