我有一个很大的csv,需要通过电子邮件发送,该文件必须压缩,否则可能会达到smtp服务器的最大限制。我正在基于数据库查询在内存中生成csv。
我正在尝试使用有关问题C# Compress and zip csv from stream的答案。但这没用(可能是由于c#版本不同,我使用的是.net core 2.2)
最终的csv是一个字符串,然后我将其转换为Stream并将其传递给答案的扩展名。
我在答案中使用的代码(略有改动):
{
public string FileName { get; set; }
public Stream FileStream { get; set; }
}
public static class ZipArchiveExtensions
{
public static Stream GenerateStreamFromString(string s)
{
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
writer.Write(s);
writer.Flush();
stream.Position = 0;
return stream;
}
public static Stream Compress(this FileModel file) => Compress(new FileModel[] { file });
public static Stream Compress(this IEnumerable<FileModel> files)
{
if (files.Any())
{
var ms = new MemoryStream();
var archive = new ZipArchive(ms, ZipArchiveMode.Create, false);
foreach (var file in files)
{
var entry = archive.add(file);
}
ms.Position = 0;
return ms;
}
return null;
}
private static ZipArchiveEntry add(this ZipArchive archive, FileModel file)
{
var entry = archive.CreateEntry(file.FileName, CompressionLevel.Fastest);
using (var stream = entry.Open())
{
file.FileStream.CopyTo(stream);
// stream.Position = 0;
stream.Close();
}
return entry;
}
}
我如何使用代码:
var stream = ZipArchiveExtensions.GenerateStreamFromString(csvStr);
var file = new FileModel { FileName = reportName + ".csv", FileStream = stream };
var compressedFile = file.Compress();
var attachment = new Attachment(compressedFile, reportName + ".zip");
await this._emailService.SendMessageAsync(reportRequest.MailTo, reportName, null, new[] { attachment });
由于某些原因,电子邮件上的结果zip文件无效。
答案 0 :(得分:3)
必须放置ZipArchive
对象以将其内容正确写入其基础流。另外,您必须将leaveOpen
标志设置为true,这样在处置档案时,compressedFile
将不会关闭。
public static Stream Compress(this IEnumerable<FileModel> files)
{
if (files.Any())
{
var ms = new MemoryStream();
using (var archive = new ZipArchive(ms, ZipArchiveMode.Create, leaveOpen: true))
{
foreach (var file in files)
{
var entry = archive.add(file);
}
}
ms.Position = 0;
return ms;
}
return null;
}