如何在Python 2.5中模拟ZipFile.open?

2023-11-29

我想将文件从 zip 中提取到特定路径,忽略存档中的文件路径。这在 Python 2.6 中非常简单(我的文档字符串比代码长)

import shutil
import zipfile

def extract_from_zip(name, dest_path, zip_file):
    """Similar to zipfile.ZipFile.extract but extracts the file given by name
    from the zip_file (instance of zipfile.ZipFile) to the given dest_path
    *ignoring* the filename path given in the archive completely
    instead of preserving it as extract does.
    """
    dest_file = open(dest_path, 'wb')
    archived_file = zip_file.open(name)
    shutil.copyfileobj(archived_file, dest_file)


 extract_from_zip('path/to/file.dat', 'output.txt', zipfile.ZipFile('test.zip', 'r'))

但在 Python 2.5 中,ZipFile.open方法不可用。我在 stackoverflow 上找不到解决方案,但是这个论坛帖子有一个很好的解决方案,利用ZipInfo.file_offset寻找 zip 中的正确点并使用zlib.decompressobj从那里解压字节。很遗憾ZipInfo.file_offset在 Python 2.5 中被删除了!

因此,考虑到 Python 2.5 中我们所拥有的就是ZipInfo.header_offset,我想我只需要解析并跳过标头结构即可自己获取文件偏移量。使用维基百科作为一个参考(我知道)我想出了这个更长而且不是很优雅的解决方案。

import zipfile
import zlib

def extract_from_zip(name, dest_path, zip_file):
    """Python 2.5 version :("""
    dest_file = open(dest_path, 'wb')
    info = zip_file.getinfo(name)
    if info.compress_type == zipfile.ZIP_STORED:
        decoder = None
    elif info.compress_type == zipfile.ZIP_DEFLATED:
        decoder = zlib.decompressobj(-zlib.MAX_WBITS)
    else:
        raise zipfile.BadZipFile("Unrecognized compression method")

    # Seek over the fixed size fields to the "file name length" field in
    # the file header (26 bytes). Unpack this and the "extra field length"
    # field ourselves as info.extra doesn't seem to be the correct length.
    zip_file.fp.seek(info.header_offset + 26)
    file_name_len, extra_len = struct.unpack("<HH", zip_file.fp.read(4))
    zip_file.fp.seek(info.header_offset + 30 + file_name_len + extra_len)

    bytes_to_read = info.compress_size

    while True:
        buff = zip_file.fp.read(min(bytes_to_read, 102400))
        if not buff:
            break
        bytes_to_read -= len(buff)
        if decoder:
            buff = decoder.decompress(buff)
        dest_file.write(buff)

    if decoder:
        dest_file.write(decoder.decompress('Z'))
        dest_file.write(decoder.flush())

请注意我如何解压并读取给出额外字段长度的字段,因为调用len on the ZipInfo.extra属性少了 4 个字节,从而导致偏移量计算不正确。也许我在这里遗漏了一些东西?

有人可以针对 Python 2.5 改进这个解决方案吗?

Edit:我应该说,克里斯亚当斯建议的显而易见的解决方案

dest_file.write(zip_file.read(name))

将会失败MemoryError对于 zip 中包含的任何大小合理的文件,因为它试图一次性将整个文件放入内存中。我有大文件,所以我需要将内容流式传输到磁盘。

另外,升级 Python 是一种显而易见的解决方案,但它完全超出了我的控制范围,而且基本上是不可能的。


还没有测试过这一点,但我在 Python 2.4 中使用了非常相似的东西

import zipfile

def extract_from_zip(name, dest_path, zip_file):
    dest_file = open(dest_path, 'wb')
    dest_file.write(zip_file.read(name))
    dest_file.close()

extract_from_zip('path/to/file/in/archive.dat', 
        'output.txt', 
        zipfile.ZipFile('test.zip', 'r'))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在Python 2.5中模拟ZipFile.open? 的相关文章

随机推荐

  • 向所有请求添加Where条件EF6

    我的大部分实体 并非全部 有两个属性称为CompanyId and Deleted 如何为所有选择请求自动插入这两个属性 而不是在整个应用程序中的每个查询上手动设置 Example db MyEntity Where me gt me Id
  • Codeigniter/PHP:将数据库查询格式化为数组

    this gt db gt select id user id gt from be users gt where id user id data user individual this gt db gt get 如果这是我的数据库查询
  • REGEXP 与 PDO Mysql

    我正在尝试在 PDO Mysql 中使用 REGEX 但出现问题 function artist list artist global DBH STH DBH gt prepare SELECT songs image artist alb
  • java、反射、内部类、

    您好 我想使用反射获取内部类的对象 但我在其中遇到了一些错误 代码是 package reflaction public class MyReflection public static void main String args thro
  • 遍历 jquery 中的嵌套表单元素

    很抱歉 如果这已经发布了 我一直在寻找无济于事 我只是想知道如何在 jquery 中循环嵌套表单 元素 元素不仅是像输入标签这样的严格表单元素 而且还有其他 html 元素 目前我有这段代码可以做到这一点 arguments i formi
  • Haskell 声明中的感叹号是什么意思?

    当我尝试使用真实的项目来驱动 Haskell 时 我遇到了以下定义 我不明白每个参数前面的感叹号是什么意思 我的书上似乎没有提到它 data MidiMessage MidiMessage Int MidiMessage 这是一个严格的声明
  • 检测 AJAX 何时更改 Web 浏览器中 DIV 中的 HTML

    通过 Web 浏览器加载页面并单击触发 AJAX 脚本的链接后 我需要检测 AJAX java 脚本何时完成将 HTML 更改加载到 div 中 由于运行 AJAX 脚本时不会触发 DocumentCompleted 事件 因此我不知道它何
  • 如何解码这段 PHP 代码?

    我想解码这段代码 我不知道它是什么 只知道它是某种代码 有人能帮助我吗
  • 如何在 EditText 上默认使用数字键盘而不强制输入数字? [复制]

    这个问题在这里已经有答案了 这个问题已经在网上其他地方询问过了 没有结果 Android 有没有办法在聚焦时显示数字软键盘EditText 但仍然允许输入任何文本 我想让用户输入数量 例如 1 kg 2 L 所以只需设置inputType
  • Oracle数据库搜索所有表中的字符串,返回行数据[重复]

    这个问题在这里已经有答案了 我需要在 Oracle 数据库中的所有表中搜索特定字符串 并返回找到该字符串的所有记录 我正在使用 SQL Developer 网上发布了几个非常有用的脚本和存储过程 它们提供了一种搜索整个数据库的方法 并且它们
  • 我可以按任意顺序将中间件应用到应用程序吗?

    在 C ASP NET 中 中间件应用程序的顺序重要吗 以下2个代码片段 public class Startup public void Configure IApplicationBuilder app IHostingEnvironm
  • 删除浏览器默认样式

    有没有办法或者声明如XHTML or HTML4这会删除元素上的默认 CSS 样式吗 Doctype 不用于样式化 有两种重要的方法可以删除所有样式并统一默认外观 标准化 csshttps necolas github io normali
  • C++ 中整数向量的序列化/反序列化

    待完成任务 我正在尝试将整数向量序列化为字符串 以便可以将其存储到文件中 使用的方法是将整数逐字节复制到缓冲区中 为此 我使用了 std copy n 函数 为了反序列化 我反向做了同样的事情 即从缓冲区逐字节复制到整数中 并将这些整数附加
  • C# 中的 PInvoke DLL

    我想将一个结构传递给 C 函数 并编写以下代码 当我运行它时 第一个函数 Foo1正在工作 然后起作用Foo出现异常 你能帮我理解问题是什么吗 C代码 typedef struct int Size char Array TTest dec
  • 使用 for 循环在数据框中创建新列来计算 R 中的值?

    我有两个数据框 df1 和 df2 group c Group 1 Group 2 Group3 Group 1 Group 2 Group3 year c 2000 2000 2000 2015 2015 2015 items c 12
  • 在 JavaScript 中对自定义对象数组进行排序

    假设我有一个 Employee 对象数组 var Employee function fname age this fname fname this age age var employees new Employee Jack 32 ne
  • 您认为什么更具可读性:?? (运算符)或使用 if

    我有一个方法会收到string 但在我可以使用它之前 我必须将其转换为int 有时可以是null我必须将其值更改为 0 今天我有 public void doSomeWork string value int SomeValue int P
  • AVAudioPlayer - 帧率下降

    我有一个简单的问题 我正在将 mp3 文件加载到 NSData 对象中 然后在游戏中使用 AVAudioPlayer 来播放它 大约每隔一秒 帧速率就会下降 您可以看到屏幕上出现卡顿现象 这并不是一个重大的减速 但明显明显并且对游戏玩法造成
  • 如何对此 Javascript/JSON 树进行递归搜索?

    我正在写一些 JavaScript 代码 我有一个如下所示的 JSON 对象 为了可读性修改了间距 var myNodes id 4 children id 1 children id 3 children id 2 chil
  • 如何在Python 2.5中模拟ZipFile.open?

    我想将文件从 zip 中提取到特定路径 忽略存档中的文件路径 这在 Python 2 6 中非常简单 我的文档字符串比代码长 import shutil import zipfile def extract from zip name de