【发布时间】:2015-04-21 14:40:56
【问题描述】:
我有一个 web api GET 方法,它返回一个 zip 文件以供下载。以下是创建 zip 存档的代码:
var resultStream = new MemoryStream();
using (var zipArchive = new ZipArchive(resultStream, ZipArchiveMode.Create, leaveOpen: true))
{
foreach (var file in files)
{
zipArchive.CreateEntryFromFile(file.Path, file.Name, CompressionLevel.Optimal);
}
}
以下是响应的填充方式:
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new ByteArrayContent(resultStream.ToArray());
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip");
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = "export_" + DateTime.Now.ToString("dd-MM-yyyy_HH-mm-ss") + ".zip";
response.Content.Headers.ContentDisposition.CreationDate = DateTime.Now;
response.Content.Headers.ContentDisposition.Size = resultStream.Length;
response.Content.Headers.ContentLength = resultStream.Length;
上面的代码工作得很好,问题是它消耗了服务器上的大量内存,当然这取决于文件大小。我尝试将结果更改为StreamContent,但这不起作用,因为响应仅返回标头并最终超时。
所以这是我的问题:
- 有没有办法避免在内存中加载所有文件,而是在创建 zip 文件时发送它?
- 在这种情况下使用 StreamContent 是否更好,如果是,我需要进行哪些更改才能使其正常工作?
- 在每种情况下,缓冲如何影响内存消耗?我尝试按照建议的in this article 实现自定义
IHostBufferPolicySelector来禁用缓冲,但它似乎没有任何效果。 - 目前可以通过导航链接、使用HttpClient或通过AJAX请求调用api操作,因此任何解决方案都必须支持所有场景。
【问题讨论】:
-
尝试使用 GZipStream 和 PushStreamContent
-
你的服务器收到多少请求?
-
你不能设置内容长度,所以需要启用块编码。
-
@AliHasan 最多 2-3 个并发请求。它是一个内部应用程序,因此使用 ByteArrayContent 仍然是一种选择。
-
您是否有任何未处理的对象?
标签: c# asp.net-web-api