我有一个API HTTPGET,可以从另一个API检索文件并将其吐出。这适用于较小的文件,但是我遇到的问题是,检索到的文件可能很大(最大2gb),而MemoryStream是一个限制。有什么想法如何在不使用磁盘的情况下流式传输文件内容并避免“内存不足”异常?
控制器:
[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();
}
}
型号:
public class ContentFile
{
public string Filename { get; set; }
public byte[] Data { get; set; }
public StreamContent DataStream { get; set; }
public string ContentType { get; set; }
}
存储库调用:
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;
}
谢谢。
答案 0 :(得分:0)
因此,不是GetContentFile
将整个流读入数组并返回它,而是返回该流。不需要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);
}