python unzip文件

解压缩zip文件

import zipfile
import os.path
import os


class ZFile(object):
    """
    文件压缩
    """

    def zip_file(self, fs_name, fz_name):
        """
        从压缩文件
        :param fs_name: 源文件名
        :param fz_name: 压缩后文件名
        :return:
        """
        flag = False
        if fs_name and fz_name:
            try:
                with zipfile.ZipFile(fz_name, mode='w', compression=zipfile.ZIP_DEFLATED) as zipf:
                    zipf.write(fs_name)
                    print(
                        "%s is running [%s] " %
                        (currentThread().getName(), fs_name))
                    print('压缩文件[{}]成功'.format(fs_name))
                if zipfile.is_zipfile(fz_name):
                    os.remove(fs_name)
                    print('删除文件[{}]成功'.format(fs_name))
                flag = True
            except Exception as e:
                print('压缩文件[{}]失败'.format(fs_name), str(e))

        else:
            print('文件名不能为空')
        return {'file_name': fs_name, 'flag': flag}

    def unzip_file(self, fz_name, path):
        """
        解压缩文件
        :param fz_name: zip文件
        :param path: 解压缩路径
        :return:
        """
        flag = False

        if zipfile.is_zipfile(fz_name):  # 检查是否为zip文件
            with zipfile.ZipFile(fz_name, 'r') as zipf:
                zipf.extractall(path)
                # for p in zipf.namelist():
                #     # 使用cp437对文件名进行解码还原, win下一般使用的是gbk编码
                #     p = p.encode('cp437').decode('gbk')  # 解决中文乱码
                #     print(fz_name, p,path)
                flag = True

        return {'file_name': fz_name, 'flag': flag}

解决中文乱码问题:

在zip标准中,对文件名的 encoding 用的不是 unicode,而可能是各种软件根据系统的默认字符集来采用(此为猜测),因此zipfile中根据文件 flag 检测的时候,只支持 cp437 和 utf-8。具体就是查找 zipfile.py 源代码找到下面的代码:

找到python3 的安装目录, 搜索 zipfile.py这个文件,改两个地方

可见编码被正确识别为utf8时的情况外,都会被识别并decode为cp437编码,但如果实际是gbk等其他编码时就变为乱码了

第一.

            if zinfo.flag_bits & 0x800:
                # UTF-8 filename
                fname_str = fname.decode("utf-8")
            else:
                # fname_str = fname.decode("cp437")
                fname_str = fname.decode("gbk")  # 这句是我添加的 解决win下中文乱码

第二..

            if flags & 0x800:
                # UTF-8 file names extension
                filename = filename.decode('utf-8')
            else:
                # Historical ZIP filename encoding
                # filename = filename.decode('cp437')
                filename = filename.decode("gbk")  # 这句是我添加的,解决win下中文乱码问题
上一篇:C# 递归压缩服务器文件夹及文件并下载


下一篇:zipfile(压缩文件)