从字符串压缩和压缩文件

时间:2019-12-19 17:52:47

标签: c# csv zip

我有一个很大的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文件无效。

1 个答案:

答案 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;
}