2011-04-28 141 views
1

我正在創建一個ZIP文件。我正在使用dotnetzip來做這件事。 我的ZIP文件的大小可能會上升到500 MB,許多用戶試圖同時下載它。在ASP.NET中將大文件寫入HttpResponse的最有效方法

什麼是我可以提供文件的最有效方式?如果給出選擇,我寧願不將文件保存在磁盤上,因爲可能會造成嚴重的磁盤空間限制。

編輯:更多關於我的使用情況:

我們是東道主,在其中有用戶在世界各地的一個內部網站託管在SharePoint 2010資產庫我們的文件。這些文件的範圍通常爲10-80 MB。用戶希望能夠一次下載多個文件。

+1

你能告訴我們更多關於用例嗎?使用網絡來處理這些大小的文件,而不會出現像設計缺陷一樣的緩存氣味 - 但當然,您的使用案例可能與更常見的案例不同。 – 2011-04-28 23:06:25

回答

2

好,理論上

對於傳統的ASP.Net應用程序,你就應該能夠編寫響應數據(字節)的HttpContext.Response.OutputStream(你如何得到HTTP響應上下文將取決於如何你處理下載請求,例如,如果你正在執行IHttpHandler那麼你會得到傳遞給你的http上下文)。

望着DotNetZip例子,它看起來像Save方法接受一個流,所以就這麼簡單

zip.Save(context.Response.OutputStream); 

如果zip文件被重複使用和下載的許多用戶來說,這將是那麼你就可以代替創建它允許您在以後複製該內存流個體反應的內容的拉鍊時寫的zip到MemoryStream

MemoryStream stream = new MemoryStream() 
zip.Save(stream); 
// Save data somewhere common (e.g. cache it) 
byte[] data = stream.ToArray(); 

爲了寫這個數據傳回的響應:

MemoryStream reader = new MemoryStream(data); 
CopyStream(reader, context.Response.OutputStream); 

有關CopyStream的實現請參閱Best way to copy between two Stream instances - C#

然而在現實

這個一秒鐘的思考,這意味着如果zip文件就是我們在內存中存儲數據的500MB 500MB - 如果這是唯一的zip文件,這可能是罰款永遠存在,但如果有3或4個,我們很快就會耗盡「內存」(即虛擬地址空間)。

解決方案?恐怕最簡單的方法是將您的壓縮,而不是保存到一個文件(即使它是由IIS不能直接送達的臨時文件)到內存流:

// To save the zip 
string filename = Path.GetTempFileName(); 
zip.Save(filename); 

// To write the file 
context.Response.TransmitFile(filename); 

你或許應該也刪除文件,當你完成。

請注意,如果您決定在多個用戶之間共享相同的壓縮文件,那麼您只需要打擾這一點 - 如果您只是基於每個用戶構建壓縮文件並使用zip.Save(OutputStream)直接將其寫入輸出流,是少了很多麻煩。我的建議是首先做簡單的方法,然後測試一下,看看你是否遇到性能問題,只需創建一次zip就可以解決。

+0

你可能會發現這個鏈接很有用,當你實現這樣的位時,「你應該也可以在完成後刪除文件。」 http://stackoverflow.com/q/2688282/150342 – Colin 2013-02-27 10:46:47

1

爲此,您可能會更好地通過使用消息隊列異步執行它。這樣,壓縮添加到隊列中,您可以獲得一臺服務器或多臺服務器。我不知道這是否符合您的要求。

我以前使用過Rabbit MQ(http://www.rabbitmq.com/)。

相關問題