2012-04-19 58 views
1

在我的django項目中,我需要發送zip文件到客戶端進行下載。此zip文件將包含從各種url下載的圖像。從內存中下載url中的圖像並在內存中創建zip存檔以發送給瀏覽器

是否有可能下載內存中的圖像,而無需將圖像文件寫入磁盤,然後將它們添加到內存本身的zip文件中,再次不將zip文件寫入磁盤並最終將zip文件發送到客戶端進行下載?

我知道,urllib2可以用於圖像下載和zip文件,用於處理zip文件,但面臨在內存本身執行這些操作的問題。所以,一些這樣的例子將非常感激。

謝謝

回答

2

用urllib2下載文件。打開一個新的ZipFile進行編寫(爲此,您需要一個StringIO對象)。將url的輸出寫入ZilpFile.writestr。將zip文件附加到django響應中。

import urllib2 
from StringIO import StringIO 

url = urllib2.urlopen('http://example.com/foo.jpg') 
f = StringIO() 
zip = zipfile.ZipFile(f, 'w') 
zip.writestr('foo.jpg', url.read()) 
response = HttpResponse(f.getvalue(), content_type="application/zip") 
response['Content-Disposition'] = 'attachment; filename=foobar.zip' 
return response 
+0

感謝您的回覆。但在客戶端,我沒有把文件保存爲dialog.I在Chrome瀏覽器中試過。 – user1283941 2012-04-19 21:21:20

+0

服務器給你什麼迴應? – John 2012-04-19 21:25:05

+0

我檢查了chrome調試器,在響應窗格中顯示了一些亂碼字符。響應標題是Connection:keep-alive Content-Disposition:attachment;文件名= foobar.zip 內容類型:應用程序/ zip 日期:2012年4月19日星期四21:19:18 GMT P3p:CP =「IDC CURA ADMa我們的IND PHY ONL COM STA」 服務器:gunicorn/0.14。 2 transfer-encoding:chunked – user1283941 2012-04-19 21:26:51

0

你能做到這一點,簡單地說:

response = urllib2.urlopen('http://..') 
img_bytes = response.read() 

,然後用ZipFile.writestr到這些字節寫入文件,Zip文件裏先前創建傳遞一個StringIO的處理程序,而不是一個真正的文件處理程序。完成文件寫入後,將其作爲HTTPResponse設置適當的MIME類型和內容配置。

但我不會爲此使用RAM。爲什麼不使用tempfile.NamedTemporaryFile?

+0

我想不出有什麼好的理由把它寫出來,除非他壓縮了大量的圖像,即使那樣我也不確定這會有多大幫助。你所做的只是添加不必要的磁盤io(這很可能是Web服務器上的限制因素) – John 2012-04-19 20:06:26

+0

這取決於該下載操作的用戶併發性。如果他從各種鏈接中隨時抓取照片,則可能需要一段時間才能清除內存。從Django文檔:默認情況下,如果上傳的文件小於2.5兆字節,Django會將上載的全部內容保存在內存中。所以這取決於使用的大小和併發性,我猜。 – 2012-04-19 20:13:35

相關問題