Python无法从大型zipfile

时间:2016-08-22 15:56:12

标签: python

我已经使用(例如)this blog post

中的技术将脚本和一些资源打包到可执行的zip文件中

该过程突然停止工作,我认为它与zip64扩展有关。当我尝试运行可执行zipfile时,我得到:

/ usr / bin / python:无法找到' 主要'模块in' /path/to/my_app.zip'

我认为唯一的变化是其中一个资源文件(磁盘映像)变大了。我已经确认__main__.py仍在归档的根目录中。 zipfile的大小曾经是600MB,现在是2.5GB。我在zipimport docs中注意到以下声明:

  

目前不支持包含存档注释的ZIP存档。

在zipfile格式上阅读the wikipedia article,我看到:

  

.ZIP文件格式允许在中心目录之后的文件末尾包含最多65,535字节数据的注释。[25]

之后,关于 zip64

  

本质上,它使用" normal"文件的中央目录条目,后跟可选的" zip64"目录条目,具有较大的字段。[29]

推断一下,听起来这可能是正在发生的事情:我的zipfile已经发展到需要zip64扩展名。 zip64扩展数据存储在注释部分,所以现在有一个活动的注释部分,而python的zipimport拒绝读取我的zip文件。

任何人都可以提供以下指导:

  1. 验证python为什么在我的zipfile中找不到__main__.py的原因
  2. 提供任何解决方法
  3. 请注意,映像文件的大小一直是16GB,但它过去只占用磁盘上的600MB(如果重要的话,它驻留在ext4文件系统上)。它现在占据>磁盘上有7GB。来自维基百科页面:

      

    原始.ZIP格式对各种事物有4 GiB限制(文件的未压缩大小,文件的压缩大小和存档的总大小)

    我使用python脚本构建zipfile,所以为了尝试解决这个问题,我在添加图像文件之前将python代码添加到zipfile。想法是python可能只是忽略注释部分并看到包含python代码但不包含大图像文件的有效zipfile。这似乎并非如此。

1 个答案:

答案 0 :(得分:0)

在zipimport.c中深入研究python源代码,我们可以看到它确实在文件的最后22个字节中查找end-of-central-directory块。如果没有找到有效的中心目录结尾,它不会从那里收回搜索(我猜这使得它不是一个兼容的zip解析器)。无论如何,它所做的是查看中心目录结束记录中报告的中心目录的偏移量和大小。 offset + size应该是中心目录结束记录的位置。如果不是,则计算实际位置和预期位置之间的差异,并将此偏移量添加到中央目录中的所有偏移量。这意味着python支持从zipfile加载模块,该文件被捕获到另一个文件的末尾。

然而,似乎2.7.6的zipimport实现(与ubuntu 14.04一起分发)对于大型zipfiles(大于> 2GB?我认为最大签名为32位长)是破坏的。但它适用于python 3.4.3(也与ubuntu 14.04一起发布)。 zipimport.c在2.7.6和2.7.12之间的某个时间发生了变化,所以它可能适用于较新的python 2。

我的解决方案是打包资源zip和代码zip,然后将它们拼凑在一起,然后使用python3而不是python2运行应用程序。我将资源zip的偏移量和大小写入代码zip中的元数据文件。代码使用此信息并filechunkio为包文件的资源zip段获取zipfile.ZipFile

不是一个很好的解决方案,但它确实有效。