胡琪

为今天工作,为明天投资,为未来孵化一些东西!

python文件操作之zip包操作

在平时的项目开发中,文件操作是非常频繁的一个场景,前面python文件操作中带领大家学些了基本的文件操作,但是还有一类特殊的文件就是压缩包文件,如jar包,apk包本质上都是压缩包,对这类文件处理要使用python中的zipfile模块。

首先来看一下ZipFile类的定义

zipfile.ZipFile

class zipfile.ZipFile(file, mode=’r’, compression=ZIP_STORED, allowZip64=True)

可以看到ZipFile包含四个参数,其中后面的三个参数都是自带默认值的参数,各个参数的含义如下:

  • file,文件的路径或者文件对象本身,如果是文件路径通常是一个字符串
  • mode,打开zip包的模式,和签名讲解的打开文件的模式一样
  • compression:压缩类型,因为zip包是压缩包,是采用某种压缩算法压缩后的文件格式,因此会存在不同的压缩类型,如ZIP_STORED, ZIP_DEFLATED, ZIP_BZIP2 or ZIP_LZMA等
  • allowZip64,该值默认为True,当zipfile大于4 GiB时,zipfile将创建使用ZIP64扩展名的ZIP文件

注意ZipFile和open一样也支持with as语句,因此好的习惯是通过with as语句来使用ZipFile,这样zipfile对象会自动调用close()函数来关闭读写操作当with语句块结束时,即使出现异常也会close(),这样能够避免我们忘记手动调用close()函数,像下面这样:

官方文档点这里:https://docs.python.org/3/library/zipfile.html

然后来看下ZipFile类常用的函数

ZipFile.namelist()

返回zip包所有的entry名称的list,注意返回的entry名称中包含目录路径,如X/Y/z.txt。

ZipFile.getinfo(name)

name为传入的entry的名称,注意需要包括目录路径,如某zip包解压后目录层级关系为X/Y/z.txt,则需传入X/Y/z.txt,若直接传入z.txt,因为该zip包中不存在该entry,因此会抛出KeyError错误,如果entry存在,则会返回和该entry名称对应的ZipInfo对象。ZipInfo对象中定义了很多有用的信息,如压缩文件的压缩类型,压缩后的大小,压缩前的大小。常用的属性及其含义如下:

  • ZipInfo.compress_type,该entry的压缩类型,常见的压缩类型包括ZIP_STORED和ZIP_DEFLATED
  • ZipInfo.compress_size,该entry压缩后的大小
  • ZipInfo.file_size,该entry压缩前的大小
  • ZipInfo.CRC ,该entry的CRC校验码

除了属性外,ZipInfo还包括一些很有用的函数,如ZipInfo.is_dir()函数可以判断该entry是目录还是文件,如果为目录返回True

ZipFile.extract(member, path=None, pwd=None)

解压出名称为member的entry到当前工作路径下,该函数各个参数含义如下:

  • member,待解压的entry名称,同样名称包含路径,如X/Y/z.txt
  • path,解压目录,默认值为None,解压到当前工作目录,如果指定了该值,则会解压到path路径下
  • pwd,解压的密码,如果该zip在压缩时进行过加密操作,则需要传入该值

ZipFile.write(filename, arcname=None, compress_type=None)

将名为filename的文件添加到zip包中,该函数各个参数含义如下:

  • filename,需要添加(写入)到zip包中的文件,通常是一个文件路径的字符串
  • arcname,添加到zip包中的文件的名称,默认为None,如果不指定该值,则默认采用和filename一样的名称
  • compress_type,压缩到zip包中时的压缩类型,如ZIP_STORED,ZIP_DEFLATED

 

虽然ZipFile为我们提供了很多API,但是很遗憾目前的python中ZipFile还未给我们提供一个不解压直接删除zip包中文件的函数,这里我们可以自己定义一个类来继承自ZipFile,然后自己实现直接删除zip包中某一个entry的函数,包括直接删除文件或者文件夹。代码如下:

在这里我们定义了一个ZipManager类继承自ZipFile类,然后自定义了remove函数用来直接删除zip包中的某一个文件,delete_dir函数来删除文件夹。这样对zip包的操作就比较完整了。

综合实例

这里实现一个操作就是替换zip包中某个文件,给一个apk文件X.apk,替换文件Y,将apk包中的Z替换为Y,要求替换后,Y的压缩类型要与原apk包中的文件保持一致。之所以选该实例,是因为很显然该实例包括了删除原zip包中的Z,添加Y到zip包中,也就是说该实例可以把ZipFile中的重要函数和属性都用上。当然要用到前面我们扩展的ZipManager类来实现直接删除某一项文件的操作。代码如下:

在这里我们用到了ZipFile的getrinfo函数来获取ZipInfo对象,然后通过ZipInfo.compress_type属性来得到该entry的压缩类型,然后调用我们扩展的ZipManager的remove函数直接删除该entry,最后调用write函数向zip包中添加文件,同时指定添加的文件的名称和压缩类型,这个实例可以说是zip包操作中综合性最高的一个操作。

 

 

注:本文首次发表于huqi.tech,请勿转载,如需转载,请注明出处:huqi.tech

 

扫描下方二维码实时接收最新技术干货推送

《python文件操作之zip包操作》

扫描二维码实时接收最新技术干货推送,而且会不定期的发布互联网名企内推机会哦!

 

打赏

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注