我将文件存储在Openstack Swift容器(对象存储)中。我通常通过这样的API来访问它们:
_oApi.Swift.GetObject(containerName, fileName, outputStream);
现在,我有一个用ASP NET Core 2.0编写的Web界面,希望用户能够下载Swift容器中存储的文件。
以下代码有一个缺点,文件首先下载到我的Web服务器,然后才在客户端开始下载。
[HttpGet]
public IActionResult Download(string id)
{
Response.Headers.Add("Content-Disposition", $"attachment; filename={fileName}");
Response.Headers.Add("Content-Length", filseSize);
Response.Headers.Add("Content-Type", "application/octet-stream");
_oApi.Swift.GetObject(containerName, fileName, Response.Body);
return View();
}
如何在不将结果缓存在Web服务器上的情况下将下载内容直接流式传输到客户端浏览器?
PS:我正在尝试使用20mb或更大的文件,因为此代码适用于小文件。
答案 0 :(得分:0)
直接将流作为结果传递,而不是先将其保存到磁盘。
以下示例结构直接取自project repository on GitHub
[HttpGet]
public async Task<IActionResult> Download(string id) {
//...
Response.Headers.Add("Content-Disposition", $"attachment; filename={fileName}");
var response = await _oApi.Swift.GetObject(containerName, fileName);
if(response.IsSuccess) {
return new FileStreamResult(response.Stream, "application/octet-stream");
}
return new NotFoundResult();
}
也有这个示例,它是根据您的示例再次采样的
public async Task<IActionResult> Download(string id) {
var headObject = await _oApi.Swift.HeadObject(containerId, id);
if (headObject.IsSuccess && headObject.ContentLength > 0) {
var fileName = headObject.GetMeta("Filename");
var contentType = headObject.GetMeta("Contenttype");
Response.Headers.Add("Content-Disposition", $"attachment; filename={fileName}");
var stream = new BufferedHTTPStream((start, end) => {
using (var response = _oApi.Swift.GetObjectRange(containerId, objectId, start, end).Result) {
var ms = new MemoryStream();
response.Stream.CopyTo(ms);
return ms;
}
}, () => headObject.ContentLength);
return new FileStreamResult(stream, contentType);
}
return new NotFoundResult();
}