Python zipfile模块学习

转载自https://www.j4ml.com/t/15270

import zipfile
import os
from zipfile import ZipFile


class ZipManage(ZipFile):

    def check(self, Name):
        # 检查 文件指针是否有效
        if self.fp == '':
            raise RuntimeError('ZIP archive is closed')
        # 检查 文件是否用 append 模式打开
        if self.mode != 'a':
            raise RuntimeError('ZIP archive Requires appended("a") mode to open')
        # 检查 文件或文件夹 是否在zip中
        is_existed = False
        for FileName in self.filelist:
           if FileName.filename.startswith(Name):
                is_existed = True;
                break;

        if is_existed == False:
            raise RuntimeError('ZIP archive not found ', Name)

    # 删除zip包中的文件
    def remove(self, szFileName):
        self.check(szFileName)

        # 获取 要删除文件在zip中的信息
        fileinfo = self.getinfo(szFileName)
        print(type(fileinfo))

        headerOffSet = fileinfo.header_offset
        fileBlockLen = len(fileinfo.FileHeader()) + fileinfo.compress_size


        # 根据要删除的文件信息, 更新zip包中其他文件的头部偏移值
        for info in self.infolist():
            if info.header_offset >= (headerOffSet + fileBlockLen):
                info.header_offset -= fileBlockLen

        # 将文件指针移动到 待删除文件的末尾
        self.fp.seek(headerOffSet + fileBlockLen)

        # 读取 zip中 待删除文件后 的全部数据
        data = self.fp.read()

        # 移动文件指针到 待删除文件的开始
        self.fp.seek(headerOffSet)

        # 覆写数据
        self.fp.write(data)

        # 截断文件
        self.fp.truncate()

        # 更新 zip 中的文件索引信息
        self._didModify = True
        self.filelist.remove(fileinfo)
        del self.NameToInfo[fileinfo.filename]

    # 删除 zip 中文件夹
    def remove_dir(self, szDirName):
        self.check(szDirName)

        # 获取 要删除文件夹在zip中的信息
        dirInfo = self.getinfo(szDirName)

        # 获取 头部信息 和 文件块的大小
        headerOffSet = dirInfo.header_offset
        fileBlockLen = 0
        for file in self.infolist():
            if file.filename.startswith(szDirName):
                fileBlockLen += (len(file.FileHeader()) + file.compress_size)


        for file_head_info in self.infolist():
            if file_head_info.header_offset >= (headerOffSet + fileBlockLen):
                file_head_info.header_offset -= fileBlockLen

        # 将文件指针移动到 待删除文件的末尾
        self.fp.seek(headerOffSet + fileBlockLen)

        # 读取 zip中 待删除文件后 的全部数据
        latedata = self.fp.read()

        # 移动文件指针到 待删除文件的开始
        self.fp.seek(headerOffSet)

        # 覆写数据
        self.fp.write(latedata)

        # 截断文件
        self.fp.truncate()


        # 更新 zip 中的文件索引信息
        self._didModify = True

        # 反向迭代删除
        for i in range(len(self.infolist())-1, -1, -1):
            info = self.infolist()[i]
            if info.filename.startswith(szDirName):
                self.filelist.remove(info)
                del self.NameToInfo[info.filename]

    # 替换 zip 文件中的信息
    def replace(self, szReplaceFilename, szNewFilePath):
        self.check(szReplaceFilename)

        if not os.path.exists(szNewFilePath):
            print(szNewFilePath,' is not existed')
            return;

        fileinfo = self.getinfo(szReplaceFilename)
        self.remove(szReplaceFilename)
        self.write(szNewFilePath,fileinfo.filename,fileinfo.compress_type)

def test_remove():
    file = ZipManage('/home/s/Desktop/1.zip', 'a')
    file.remove('1/1/2/22/test.txt')

def test_remove_dir():
    file = ZipManage('/home/s/Desktop/1.zip', 'a')
    file.remove_dir('1/1/2/22/')

def test_replace():
    file = ZipManage('/home/s/Desktop/1.zip', 'a')
    file.replace('1/1/test.txt', '/home/s/Desktop/test.txt')

你可能感兴趣的:(Python zipfile模块学习)