Python 如何从一组流生成Zip并使用Zip数据生成流?

Python 如何从一组流生成Zip并使用Zip数据生成流?,python,django,stream,zip,Python,Django,Stream,Zip,我有一个管理一组文件的应用程序,但这些文件实际上存储在Rackspace的CloudFiles中,因为大多数文件都是~100GB。我使用Cloudfile的TempURL特性来允许单个文件,但有时,用户会希望下载一组文件。但是下载所有这些文件并生成本地Zip文件是不可能的,因为服务器只有40GB的磁盘空间 从用户的角度来看,我想像GMail在收到一封包含多张图片的电子邮件时那样实现它:它给你一个链接,让你下载一个包含所有图片的Zip文件,下载是即时的 如何使用Python/Django实现这一点

我有一个管理一组文件的应用程序,但这些文件实际上存储在Rackspace的CloudFiles中,因为大多数文件都是~100GB。我使用Cloudfile的TempURL特性来允许单个文件,但有时,用户会希望下载一组文件。但是下载所有这些文件并生成本地Zip文件是不可能的,因为服务器只有40GB的磁盘空间

从用户的角度来看,我想像GMail在收到一封包含多张图片的电子邮件时那样实现它:它给你一个链接,让你下载一个包含所有图片的Zip文件,下载是即时的


如何使用Python/Django实现这一点?由于迭代器的输出,我已经发现并看起来很有希望,但它仍然只接受文件路径作为参数,并且
writestr
方法需要一次获取所有文件数据(~100GB)。

请检查此项-它是Python标准库的一部分:


您可以给它一个打开的文件或类似文件的对象。

请检查此项-它是Python标准库的一部分:

您可以给它一个打开的文件或类似文件的对象。

您可以使用。下面是一个使用s3的示例,您可以非常轻松地创建一个rackspace clouldfile源。创建一个客户编写器(而不是sinks.Objects)将数据流传输到其他地方,并创建自定义转换器来转换数据流

from tubing.ext import s3
from tubing import pipes, sinks
output = s3.S3Source(bucket, key) \
    | pipes.Gunzip() \
    | pipes.Split(on=b'\n') \
    | sinks.Objects()
print len(output)
你可以用。下面是一个使用s3的示例,您可以非常轻松地创建一个rackspace clouldfile源。创建一个客户编写器(而不是sinks.Objects)将数据流传输到其他地方,并创建自定义转换器来转换数据流

from tubing.ext import s3
from tubing import pipes, sinks
output = s3.S3Source(bucket, key) \
    | pipes.Gunzip() \
    | pipes.Split(on=b'\n') \
    | sinks.Objects()
print len(output)

由于Python3.5可以创建包含大量文件/文件夹的压缩块流。您可以使用不可见的流。所以现在不需要使用。 看看我的答案

这里有一个活生生的例子:

如果没有filepath,但有字节块,则可以从示例中排除
open(path,'rb')作为条目
,并用字节块替换
iter(lambda:entry.read(16384),b')
。并手动准备ZipInfo:

zinfo = ZipInfo(filename='any-name-of-your-non-existent-file', date_time=time.localtime(time.time())[:6])
zinfo.compress_type = zipfile.ZIP_STORED
# permissions:
if zinfo.filename[-1] == '/':
   # directory
   zinfo.external_attr = 0o40775 << 16   # drwxrwxr-x
   zinfo.external_attr |= 0x10           # MS-DOS directory flag
else:
   # file
   zinfo.external_attr = 0o600 << 16     # ?rw-------
zinfo=ZipInfo(filename='any-name-of-your-invision-file',date\u time=time.localtime(time.time())[:6])
zinfo.compress_type=zipfile.ZIP_存储
#权限:
如果zinfo.filename[-1]='/':
#目录

zinfo.external_attr=0o40775因为Python 3.5可以创建包含大量文件/文件夹的压缩块流。您可以使用不可见的流。所以现在不需要使用。 看看我的答案

这里有一个活生生的例子:

如果没有filepath,但有字节块,则可以从示例中排除
open(path,'rb')作为条目
,并用字节块替换
iter(lambda:entry.read(16384),b')
。并手动准备ZipInfo:

zinfo = ZipInfo(filename='any-name-of-your-non-existent-file', date_time=time.localtime(time.time())[:6])
zinfo.compress_type = zipfile.ZIP_STORED
# permissions:
if zinfo.filename[-1] == '/':
   # directory
   zinfo.external_attr = 0o40775 << 16   # drwxrwxr-x
   zinfo.external_attr |= 0x10           # MS-DOS directory flag
else:
   # file
   zinfo.external_attr = 0o600 << 16     # ?rw-------
zinfo=ZipInfo(filename='any-name-of-your-invision-file',date\u time=time.localtime(time.time())[:6])
zinfo.compress_type=zipfile.ZIP_存储
#权限:
如果zinfo.filename[-1]='/':
#目录

zinfo.external_attr=0o40775感谢@dstromberg,但它仍然无法解决将流或数据迭代器写入Zip文件的问题。该方法仍然需要一个filepath作为第一个参数。接近我需要的,但它读取整个图像数据并将其传递给方法,但当文件为+100GB时,这是不可能的。感谢@dstromberg,但它仍然无法解决将流或数据迭代器写入Zip文件的问题。该方法仍然需要一个filepath作为第一个参数。接近我需要的,但它读取整个图像数据并将其传递给方法,但当文件为+100GB时,这是不可能的。