【发布时间】:2020-02-04 19:12:39
【问题描述】:
现在我有一个 api 可以得到很多结果(800k),它应该将它们解析并流式传输为 CSV。 我拥有的(某种)工作代码是这样的
var query = context.address.AsNoTracking();
MemoryStream memoryStream = new MemoryStream();
StreamWriter writer = new StreamWriter(memoryStream);
foreach (var row in query)
{
writer.WriteLine(row.Name+","+row.Surname+","+row.BirthDate);
}
writer.Flush();
memoryStream.Seek(0, SeekOrigin.Begin);
return new FileStreamResult(memoryStream, "application/octet-stream")
{
FileDownloadName = "DataFile.csv"
};
但是,这似乎将所有内容都放入内存,并使用 300 mb 的内存进行存储。 据我了解,这发生在 foreach 语句中。有没有办法让我写下这条线,流式传输它,然后从内存中处理它?我的目标是在不使用太多内存的情况下实现类似的目标
我也试过这种方式,一次通话有效, 但是如果同时进行多个api调用,就会出现奇怪的行为
public async Task makeDif()
{
//var query = context.Adresar.AsNoTracking();
var query = context.Adresar.Select(x => string.Join(",", x.Ime, x.Prezime, x.Datarag + Environment.NewLine)).AsNoTracking();
Response.ContentType = "application/json";
Response.BodyWriter.WriteAsync(Encoding.UTF8.GetBytes("ime,prezime,datarag" + Environment.NewLine));
foreach (var row in query)
{
await Response.BodyWriter.WriteAsync(Encoding.UTF8.GetBytes(row));
}}
【问题讨论】:
-
您可以使用临时文件来缓冲结果吗?所以首先写入文件,而不是内存流,然后使用
Response.TransmitFile(filePath)进行传输 -
我想这可能是一种解决方法,但仍然不能完全解决我的 .我尝试使用 yield return 来执行此操作,但这不会返回完整的 csv 文件,而是返回很多行。
-
问题是
MemoryStream,而不是FileStreamResult。该代码在返回之前将所有内容缓存在内存中。一个快速简单的解决方法是将数据导出到一个临时文本文件并返回该文件
标签: c# asp.net-core .net-core entity-framework-core