首页 > 其他分享 >zip文件压缩解压

zip文件压缩解压

时间:2023-11-07 21:46:48浏览次数:34  
标签:解压 obj zip 压缩 压缩文件 file test x00

zip文件压缩解压

使用 python 操作 zip 文件,压缩和解压。

压缩

压缩文件时,可以将压缩文件保存在本地或保存在内存中,将压缩文件保存在内存中时,方便后续使用,比如直接返回给前端,也就不用再执行删除操作。

import zipfile
from pathlib import Path
from io import BytesIO


def zip_to_file():
    """压缩文件保存到文件中"""
    zip_file = Path('./test.zip')
    with zipfile.ZipFile(zip_file, 'w', zipfile.ZIP_DEFLATED) as zip_obj:
        # 将字符串写入文件压缩
        zip_obj.writestr('test.txt', 'test file')
        # 压缩本地文件
        f = Path('./test.json')
        if f.exists():
            zip_obj.write(f, 'test.json')


def zip_to_mem():
    """压缩文件保存到内存中"""
    with BytesIO() as bio, zipfile.ZipFile(bio, 'w', zipfile.ZIP_DEFLATED) as zip_obj:  # 使用 BytesIO 接收压缩文件
        # 将字符串写入文件压缩
        zip_obj.writestr('test.txt', 'test file')
        # 压缩本地文件
        f = Path('./test.json')
        if f.exists():
            zip_obj.write(f, 'test.json')
        # 保存数据时,需要先手动 close,否则最后写入的文件会缺少一部分数据
        zip_obj.close()
        # 将内存中的数据保存到文件中方便展示效果,实际中可以直接发送给前端或其他处理
        with open('test.zip', 'wb') as fw:
            fw.write(bio.getvalue())


if __name__ == '__main__':
    zip_to_mem()

问题

当把压缩文件保存在 BytesIO 中时,按照以下方式保存时,使用 zipfile 去解压压缩文件,报错zipfile.BadZipFile: File is not a zip file,但用其他压缩软件可以正常解压。

with BytesIO() as bio, zipfile.ZipFile(bio, 'w', zipfile.ZIP_DEFLATED) as zip_obj:  # 使用 BytesIO 接收压缩文件
    # 将字符串写入文件压缩
    zip_obj.writestr('test.txt', 'test file')
    # 压缩本地文件
    f = Path('./test.json')
    if f.exists():
        zip_obj.write(f, 'test.json')
    # 将内存中的数据保存到文件中方便展示效果,实际中可以直接发送给前端或其他处理
    with open('test.zip', 'wb') as fw:
        fw.write(bio.getvalue())

检查 bio 中数据后,发现在 ZipFile 对象close方法中还会调用_write_end_record写入数据,而使用上面的保存方式时,在写入本地文件时,ZipFile 对象还没有调用close方法,导致最后写入的数据缺少一部分,因此在写入本地文件前,手动调用close方法。

异常数据:b'PK\x03\x04\x14\x00\x00\x00\x08\x00\x95\x8d[W\xc1kd\xf2\x0b\x00\x00\x00\t\x00\x00\x00\x08\x00\x00\x00test.txt+I-.QH\xcb\xccI\x05\x00'
正常数据:b'PK\x03\x04\x14\x00\x00\x00\x08\x00\x95\x8d[W\xc1kd\xf2\x0b\x00\x00\x00\t\x00\x00\x00\x08\x00\x00\x00test.txt+I-.QH\xcb\xccI\x05\x00PK\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\x95\x8d[W\xc1kd\xf2\x0b\x00\x00\x00\t\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x01\x00\x00\x00\x00test.txtPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x006\x00\x00\x001\x00\x00\x00\x00\x00'

解压

可以读取本地压缩文件或内存中压缩文件,然后解压到本地目录或内存中

import json
import zipfile
from pathlib import Path


def unzip_to_file():
    """压缩到文件中"""
    zip_file = Path('./test.zip')
    with zipfile.ZipFile(zip_file, 'r') as zip_obj:
        # 直接解压在当前目录
        zip_obj.extractall()


def unzip_to_mem():
    """解压到内存中"""
    zip_file = Path('./test.zip')
    with zipfile.ZipFile(zip_file, 'r') as zip_obj:
        # 循环压缩包中的所有文件
        for file_info in zip_obj.filelist:
            # 预防压缩炸弹,限制解压文件大小
            if file_info.file_size > 1024 * 1024 * 2:
                print(f'{file_info.filename} 文件大小异常')
                break
            if file_info.filename == 'test.txt':
                # 读取文件打印文件数据
                print(zip_obj.open(file_info).read())


def unzip_from_to_mem():
    """解压到内存中"""
    zip_file = Path('./test.zip')
    # 示例为了演示,先使用 open 打开文件,再传入 ZipFile,实际中,数据可能来自于前端上传等
    with open(zip_file, 'rb') as f, zipfile.ZipFile(f, 'r') as zip_obj:
        # 循环压缩包中的所有文件
        for file_info in zip_obj.filelist:
            # 预防压缩炸弹,限制解压文件大小
            if file_info.file_size > 1024 * 1024 * 2:
                print(f'{file_info.filename} 文件大小异常')
                continue
            if file_info.filename == 'test.json':
                # 读取文件打印文件数据
                print(json.loads(zip_obj.open(file_info).read()))


if __name__ == '__main__':
    unzip_from_to_mem()

PS

  1. 在读取内存中压缩文件时,示例是使用 open 打开文件,仅作为示例,实际中,应该是前端上传数据或其他方式
  2. 当使用 flask 接收上传的压缩文件时,如果后面会多次使用该数据,需要先将数据读取出来方便后续使用bytes_io = BytesIO(request.files.get('file').stream.read())

标签:解压,obj,zip,压缩,压缩文件,file,test,x00
From: https://www.cnblogs.com/shouwangrenjian/p/17816088.html

相关文章

  • 自解压捆绑木马上线
    自解压捆绑木马使用CS生成一个木马文件将木马跟一个正常的文件捆绑在一起,当点捆绑生成的EXE文件就会执行木马和正常的文件。选中木马文件和一个正常的文件,选择添加到压缩文件常规-勾选创建自解压格式压缩文件并修改压缩文件名高级-点击自解压选项常规-填写解压路径设置-......
  • 将两个列表合并成一个字典 dict(zip())方法
    假设你有如下两个list:keys=['name','age','food']values=['Monty',42,'spam']如何转变成:a_dict={'name':'Monty','age':42,'food':'spam'}解决方法:d......
  • linux其他命令(查找,软链接,打包和压缩,软件安装)笔记
     1,查找文件 * 是通配符,代表任意字符,0到多个。find路径 -name "*.txt" :查找在路径下所有以.txt结尾的文件。 2,软链接  (1)将桌面目录下的1.txt移动到a/b/c目录下 (2)在桌面目录下新建1.txt的软链接1_xiangdui,使用相对路径 使用绝对路径 用......
  • 状态压缩DP
    关于状态表示形式的优化方式。使用场景:需要记录不超过二进制数位(通常22位以内)的bool信息的DP问题。常见的位操作简单操作任何二进制数位&1得到它本身。任何二进制数位^1则取反。任何二进制数位&0则赋值为0。任何二进制数位|1则赋值为1。混合操作(n>>k&1)......
  • WinRAR6.11无广告 - 老牌压缩软件知名产品
       WinRAR是一款功能强大的压缩包管理器,它是档案工具RAR在 Windows环境下的图形界面。该软件可用于备份数据,缩减电子邮件附件的大小,解压缩从Internet上下载的RAR、ZIP及其它类型文件,并且可以新建RAR及ZIP格式等的压缩类文件。从5.60版开始,WinRAR启用了新的图标,但用户......
  • 保姆级教学之解决Windows系统下shutil zipfile解压缩中文乱码问题
    使用shutil,zipfile模块解压文件,若待解压文件路径中带有中文,则会出现一下乱码情况。解决方案:直接对python库文件zipfile.py进行修改即可。以本人正在使用的Python3.10.4版为例。以下时具体操作流程。1、找到python所在文件路径如不知道python装在哪里,可以利用python的内置模块sys的s......
  • PDM|CATIA|压缩分包——数模文件太大,我想要压缩后分包,如何操作
    如果您想要压缩数模文件并进行分包,可以按照以下步骤进行操作:选择您需要分卷压缩的文件,右键点击并选择“添加到压缩文件”。在弹出的窗口中,选择“自定义”选项,然后设置压缩分卷大小。您可以选择预设的压缩分卷大小,也可以手动输入自己需要的大小。在“压缩文件格式”中选择合适......
  • 并查集,路径压缩
    目录并查集并查集路径压缩并查集并查集:(union-findsets)是一种简单的用途广泛的集合.并查集是若干个不相交集合,能够实现较快的合并和判断元素所在集合的操作,应用很多,如其求无向图的连通分量个数、最小公共祖先、带限制的作业排序,还有最完美的应用:实现Kruskar算法求最小生成树。从......
  • Linux zip命令:压缩文件或目录
    我们经常会在Windows系统上使用“.zip”格式压缩文件,其实“.zip”格式文件是Windows和Linux系统都通用的压缩文件类型,属于几种主流的压缩格式(zip、rar等)之一,是一种相当简单的分别压缩每个文件的存储格式,本节要讲的zip命令,类似于Windows系统中的winzip压缩程序,其基本格......
  • rust中使用zip crate解压.gz文件
    添加所需的库到Cargo.toml文件中:zip="0.6.6"直接上代码,都在酒里了.usestd::fs::File;usestd::io::{Read,Write};usestd::process::exit;usestd::path::{Path,PathBuf};usezip::ZipArchive;fnmain(){//======设置输入输出路径======letzip_......