Python工具箱系列(四十三)

发布时间 2023-09-27 15:22:49作者: 西安衍舆航天

tar文件操作

tar命令是Unix/Linux平台用的最多的命令之一。原始的tar只具备打包和解包的功能:Tape ARchive,本义就是把文件打包备份到磁带机。GNU为tar增加了很多新功能,比如支持各种压缩格式。在Unix中一切都是文件:普通文件,文件夹,符号链接,设备文件等等。tar包就是由一个个文件顺序排列而成,每个文件由两部分组成:文件头和文件内容。而文件头用C风格描述如下。

struct header
{                       /* byte offset */
  char name[100];       /*   0 */   文件名
  char mode[8];         /* 100 */   用户权限
  char uid[8];          /* 108 */   user id
  char gid[8];          /* 116 */   group id
  char size[12];        /* 124 */   文件大小
  char mtime[12];       /* 136 */   修改时间
  char chksum[8];       /* 148 */   校验值
  char typeflag;        /* 156 */   文件类型标志
  char linkname[100];   /* 157 */   符号链接指向
  char magic[6];        /* 257 */   
  char version[2];      /* 263 */
  char uname[32];       /* 265 */   user name
  char gname[32];       /* 297 */   group name
  char devmajor[8];     /* 329 */   设备文件 major
  char devminor[8];     /* 337 */   设备文件 minor
  char prefix[155];     /* 345 */
                        /* 500 */
};

/* typeflag的定义如下。*/
文件类型标志定义,包含了所有 Unix 系统中的文件类型

#define REGTYPE  '0'            /* regular file */
#define LNKTYPE  '1'            /* link */
#define SYMTYPE  '2'            /* reserved */
#define CHRTYPE  '3'            /* character special */
#define BLKTYPE  '4'            /* block special */
#define DIRTYPE  '5'            /* directory */
#define FIFOTYPE '6'            /* FIFO special */
#define CONTTYPE '7'            /* reserved */

所以tar包无所不能,可以在解压后恢复文件的权限、文件owner和group、修改时间等等各种属性。除了正常的文件,连设备文件也可以打包,因为如此,tar命令可以用来备份整个Linux操作系统,因此,tar也是运维人员的至爱之一。

python为操作tar文件提供了相当完善的支持。与zipfile等标准库的操作类似,以下代码演示了相关的基本操作。

import tarfile

outputname = r'd:\demo.tar'
outputdir = r'd:\test'
filelist = [r'D:\dev\gotoolkits\figures\book01.jpg',r'D:\dev\gotoolkits\figures\python-zlib01.png']

def taradd(tarname,filelist,mode='w'):
    with tarfile.open(tarname,mode) as output:
        for file in filelist:
            output.add(file)

def tarinfo(tarname):
    with tarfile.open(tarname,'r') as output:
        print(output.getmembers())

def extractall(tarname):
    with tarfile.open(tarname,'r') as output:
        output.extractall(path=outputdir)

def extractonebyone(tarname):
    with tarfile.open(tarname,'r') as output:
        for item in output.getmembers():
            output.extract(item,path=outputdir)
        

# 打包单个文件
taradd(outputname,[r'D:\dev\gotoolkits\README.md'])

# 打包许多文件
taradd(outputname,filelist) 

# 显示压缩文件内容
tarinfo(outputname)
  
# 解压所有的文件
extractall(outputname)

# 小内存解压所有的文件
extractonebyone(outputname)

# 打包并压缩整个目录
taradd(f'{outputname}.gz',[r'd:\dev\gotoolkits'],'w:gz') 
tarinfo(f'{outputname}.gz')

tarfile库功能非常强大,不仅能够打包单个文件,而且能够打包整个目录。此外,在打包的同时能够进行压缩。正如上述代码所列,可以输入压缩模式。以写入为例,模式有以下几种:

  • 'w'或'w:' :打开用于未压缩的写入。
  • 'w:gz':打开用于 gzip 压缩的写入。
  • 'w:bz2':打开用于 bzip2 压缩的写入。
  • 'w:xz':打开用于 lzma 压缩的写入。

本示例程序上,创建了tar.gz打包压缩包。使用tar命令行工具可以方便的解开。tarfile库为使用python进行灵活的DevOps提供了基础。