使用App Engine生成并返回ZIP文件是否可行?

20

我有一个小项目非常适合使用Google App Engine,但是实现它需要能够生成并返回ZIP文件。

据我所知,由于App Engine的分布式特性,ZIP文件无法以传统方式“内存中”创建。基本上必须在单个请求/响应周期中生成并发送。

Python zip模块在App Engine环境中是否存在?

3个回答

33

在appengine上可以使用zipfile,以下是重新编写的示例:

from contextlib import closing
from zipfile import ZipFile, ZIP_DEFLATED

from google.appengine.ext import webapp
from google.appengine.api import urlfetch

def addResource(zfile, url, fname):
    # get the contents      
    contents = urlfetch.fetch(url).content
    # write the contents to the zip file
    zfile.writestr(fname, contents)

class OutZipfile(webapp.RequestHandler):
    def get(self):
        # Set up headers for browser to correctly recognize ZIP file
        self.response.headers['Content-Type'] ='application/zip'
        self.response.headers['Content-Disposition'] = \
            'attachment; filename="outfile.zip"'    

        # compress files and emit them directly to HTTP response stream
        with closing(ZipFile(self.response.out, "w", ZIP_DEFLATED)) as outfile:
            # repeat this for every URL that should be added to the zipfile
            addResource(outfile, 
                'https://www.google.com/intl/en/policies/privacy/', 
                'privacy.html')
            addResource(outfile, 
                'https://www.google.com/intl/en/policies/terms/', 
                'terms.html')

1
请注意,App Engine 的响应大小限制为10MB,因此您不能返回大于该大小的zip文件。也许可以使用新的Files API(SDK 1.4.3)创建zip文件,将其存储在Blobstore中,然后返回Blob。 - Bryce Cutt
这个答案在 'buf=zipf.read(2048)' 处失败了;之前没有提到过 'zipf',请使用下面的答案。 - Justin
1
如果您正在复制粘贴并使用其他数据(特别是直接来自数据存储的数据),请确保对文件名和内容进行编码,例如 contents.encode('utf-8'),因为这没有标准,可能会导致错误。 - Morris Fauntleroy
1
我一直收到以下错误信息:AttributeError: 'Response' object has no attribute 'tell' - 有什么想法吗? - Chris
1
Webapp在GAE中已不再可用。根据webapp2官方文档:“响应会将所有输出缓冲到内存中,然后在处理程序退出时发送最终输出。webapp2不支持向客户端流式传输数据。”因此,看起来这段代码实际上并没有像答案建议的那样流式传输响应。 - ACEGL
显示剩余2条评论

9
import zipfile
import StringIO

text = u"ABCDEFGHIJKLMNOPQRSTUVWXYVabcdefghijklmnopqqstuvweyxáéöüï东 廣 広 广 國 国 国 界"

zipstream=StringIO.StringIO()
file = zipfile.ZipFile(file=zipstream,compression=zipfile.ZIP_DEFLATED,mode="w")
file.writestr("data.txt.zip",text.encode("utf-8"))
file.close()
zipstream.seek(0)
self.response.headers['Content-Type'] ='application/zip'
self.response.headers['Content-Disposition'] = 'attachment; filename="data.txt.zip"'
self.response.out.write(zipstream.getvalue())

2

来自Google App Engine是什么

您可以上传其他第三方库与您的应用程序一起使用,只要它们是用纯Python实现的并且不需要任何不支持的标准库模块。

因此,即使默认情况下不存在,您也可以(可能)自己包含它。(我说“可能”是因为我不知道Python zip库是否需要任何“不支持的标准库模块”。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接