从Python中不可查找的流中增量读取单个条目ZIP文件

从Python中不可查找的流中增量读取单个条目ZIP文件,python,zip,zipfile,Python,Zip,Zipfile,我们通常需要解压缩合作伙伴通过HTTPS托管的超大(未加密)ZIP文件。通常,ZIP文件格式(如下所示)需要完整下载,以便能够查看“中心目录”数据以识别文件条目;然而,在我们的例子中,我们可以假设只有一个大文本文件被压缩,我们可以立即开始提取和解析数据,而不需要等待压缩文件缓冲 如果我们使用C#,我们可以使用它优雅地处理这个模式 然而,Python标准库的zipfile模块似乎不支持这种类型的流媒体;它假定类似于输入文件的对象是可查找的,所有教程都指向先迭代namelist(),以查找中心目录数

我们通常需要解压缩合作伙伴通过HTTPS托管的超大(未加密)ZIP文件。通常,ZIP文件格式(如下所示)需要完整下载,以便能够查看“中心目录”数据以识别文件条目;然而,在我们的例子中,我们可以假设只有一个大文本文件被压缩,我们可以立即开始提取和解析数据,而不需要等待压缩文件缓冲

如果我们使用C#,我们可以使用它优雅地处理这个模式

然而,Python标准库的
zipfile
模块似乎不支持这种类型的流媒体;它假定类似于输入文件的对象是可查找的,所有教程都指向先迭代
namelist()
,以查找中心目录数据,然后再迭代
open(name)
,以查找回文件条目

StackOverflow上的许多其他示例建议使用
BytesIO(response.content)
,这可能会以流式传输方式传输内容;但是,.请求库中的内容会消耗整个流,并将整个内容缓冲到内存中

是否有另一种方法可以使用
zipfile
或第三方Python库以完全流式方式执行此操作

是否有另一种方法可以使用zipfile或第三方Python库以完全流式方式完成此操作

是:可以做到[完全披露:基本上是我写的]

我们通常需要解压缩合作伙伴通过HTTPS托管的超大(未加密)ZIP文件

自述文件中的示例显示了如何使用
流解压缩
httpx

从流\u解压导入流\u解压
进口httpx
def压缩块():
#任何生成zip文件的iterable
使用httpx.stream('GET','https://www.example.com/my.zip“)作为r:
从r.iter_字节()得到的收益
对于文件名、文件大小、流中的解压块解压(zipped_chunks()):
对于解压块中的块:
打印(块)
如果只需要第一个文件,可以在第一个文件之后使用
break

for file_name, file_size, unzipped_chunks in stream_unzip(zipped_chunks()):
    for chunk in unzipped_chunks:
        print(chunk)
    break

通常,ZIP文件格式(如下所示)需要完整下载才能查看“中心目录”数据以识别文件条目

这并不完全正确

每个文件都有一个包含其名称的“本地”头,当任何成员文件的压缩数据结束时(通过本地头中的信息(如果存在)或来自压缩数据本身),可以计算出该文件。虽然在结尾的中央文件目录中有更多信息,但如果您只需要文件的名称+字节,则可以在下载时开始解压缩包含多个文件的ZIP文件


我不能说它在所有情况下都是绝对可能的:从技术上讲,ZIP允许许多不同的压缩算法,而我还没有对它们进行全面的研究。但是,对于最常用的DEFLATE,这是可能的。

一般来说,您想要做的是不可能的。但是,对于仅由一个文件组成的zip文件的特殊情况,您可以从文件的开头开始,手动读取第一个文件(并且仅读取)条目,然后自己解压缩以下数据(使用
zlib
)。