问题描述
我需要一个使用.Net Core API从数据库中将CSV文件导出为ZIP的API 所以我就这样:-
这是我正在使用的代码
[HttpGet("exportAsZip")]
public FileResult DownloadZipFileasas()
{
//Create temp CSV file
var cc = new CsvConfiguration(new System.Globalization.CultureInfo("en-US"));
using (MemoryStream ms = new MemoryStream())
{
var query = _context.AbdaInaktivProtokoll.Take(50).ToList();
using (var sw = new StreamWriter(stream: ms,encoding: new UTF8Encoding(true)))
{
using (var cw = new CsvWriter(sw,cc))
{
cw.WriteRecordsAsync(query);
}
var tempData = File(ms.ToArray(),"text/csv","data.csv");
//System.IO.File.copy(@"C:\Temp\data.csv",@"C:\Temp\data.csv");
//string fileName = Path.Combine(@"C:\Temp\data.csv","data.csv");
}
//Compressing CSV file
using (ZipArchive arch = new ZipArchive(ms,ZipArchiveMode.Create,true))
{
arch.CreateEntryFromFile(@"C:\Temp\data.csv","data.csv");
}
MemoryStream dolly = new MemoryStream(ms.ToArray());
using (FileStream file = new FileStream(@"C:\Temp\data.csv",FileMode.OpenorCreate,FileAccess.ReadWrite))
{
byte[] bytes = new byte[dolly.Length];
dolly.ReadAsync(bytes,(int)dolly.Length);
file.WriteAsync(bytes,bytes.Length);
file.FlushAsync();
dolly.Close();
//Delete Csv temp file after it compressed
file.disposeAsync();
System.IO.File.Delete(@"C:\Temp\data.csv");
Response.Headers.Add("Content-disposition","attachment; filename=Dateien Exportieren_" + (DateTime.UtcNow.ToShortDateString()) + ".zip");
return File(bytes,"application/zip");
}
}
}
System.ObjectdisposedException: Cannot access a closed Stream.
解决方法
我试图跟踪您的代码实际在做什么,而字节和流的混乱实在太多了。
您要处理多少csv数据?您应该尝试直接从csv编写器编写zip文件。
是否要在ram中创建整个zip文件,然后将其发送给客户端。通常,您可以指定http内容长度标头。
var ms = new MemoryStream();
using (var zip = new ZipArchive(ms,ZipArchiveMode.Create,true)){
var entry = zip.CreateEntry("data.csv");
using var sw = new StreamWriter(entry.Open(),Encoding.UTF8);
using var cw = new CsvWriter(sw,cc);
await cw.WriteRecordsAsync(query);
}
ms.Seek(0,SeekOrigin.Begin);
return File(ms,"application/zip",$"Dateien Exportieren_{DateTime.UtcNow.ToShortDateString()}.zip" );
还是您要直接以http块模式流式传输zip文件,而根本不需要服务器上有很大的缓冲区。