2011-04-28 135 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/)。

相关问题