[英]How do I stream a large file from api to api without using disk and running out of memory?
I have a API HTTPGET that retrieves a file from another API, and spits it out. 我有一个API HTTPGET,可以从另一个API检索文件并将其吐出。 This works for smaller files, but the problem I'm having is that the files retrieved can be rather large in size (up to 2gb), and the MemoryStream is a limitation.
这适用于较小的文件,但是我遇到的问题是,检索到的文件可能很大(最大2gb),而MemoryStream是一个限制。 Any ideas how to stream the file content without using disk and avoiding the 'out of memory' exception?
有什么想法如何在不使用磁盘的情况下流式传输文件内容并避免“内存不足”异常?
Controller: 控制器:
[Route("{id}/file", Name = "GetContentFile")]
[HttpGet]
public IHttpActionResult GetContentFile(string id)
{
if (String.IsNullOrEmpty(id))
return BadRequest();
ContentFile cfl = new ContentFile();
var ret = new HttpResponseMessage(HttpStatusCode.OK);
try
{
cfl = otcrepo.GetContentFile(id);
var mstream = new MemoryStream(cfl.Data);
ret.Content = new StreamContent(mstream);
ret.Content.Headers.ContentType = new MediaTypeHeaderValue(cfl.ContentType);
ret.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
}
catch
{
return InternalServerError();
}
if (cfl != null)
{
ResponseMessageResult responseMessageResult = ResponseMessage(ret);
return responseMessageResult;
}
else
{
return NotFound();
}
}
Model: 模型:
public class ContentFile
{
public string Filename { get; set; }
public byte[] Data { get; set; }
public StreamContent DataStream { get; set; }
public string ContentType { get; set; }
}
Repository call: 储存库调用:
public ContentFile GetContentFile(string id)
{
ContentFile fl = new ContentFile();
using (var htc = new HttpClient())
{
var response = htc.GetAsync(ConfigurationManager.AppSettings["BaseUrl"] + "/api/v2/nodes/" + id + "/content/").Result;
fl.Data = response.Content.ReadAsByteArrayAsync().Result;
fl.ContentType = response.Content.Headers.GetValues("Content-Type").FirstOrDefault();
}
return fl;
}
Thanks. 谢谢。
So instead of GetContentFile
reading the complete stream into an array and returning it we return the stream. 因此,代替
GetContentFile
将完整的流读入数组并返回它,我们返回流。 Than there is no need for the MemoryStream
. 不需要
MemoryStream
。
[Route("{id}/file", Name = "GetContentFile")]
[HttpGet]
public async Task<IHttpActionResult> GetContentFile(string id)
{
...
var result = await otcrepo.GetContentFile(id);
ret.Content = new StreamContent(result.stream);
ret.Content.Headers.ContentType = new MediaTypeHeaderValue(result.contentType);
...
}
public async Task<(Stream stream, string contentType)> GetContentFile(string id)
{
var htc = new HttpClient()
var response = await htc.GetAsync(ConfigurationManager.AppSettings["BaseUrl"] + "/api/v2/nodes/" + id + "/content/");
var stream = await response.Content.ReadAsStreamAsync();
var contentType = response.Content.Headers.GetValues("Content-Type").FirstOrDefault();
return (stream, contentType);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.