如何创建包含文件的 zip 存档并将其附加到 zip 存档?

How to create a zip archive with files and attach it to a zip archive?

我有很多文件需要归类归档,所有这些归档都需要放入归档中。

using (var memoryStream = new MemoryStream())
{
    foreach (var (day, _messages) in messages.GroupBy(x => x.Date).ToDictionary(x => x.Key, x => x.ToList()))
    {
        using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
        {
            using (var archiveByDay = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
            {
                foreach (var message in _messages)
                {
                    var fileInArchive = archiveByDay.CreateEntry($"{message.FileName}", CompressionLevel.Fastest);

                    var renderer = XmlHelper.SerializeWin1251(message);

                    using (var entryStream = fileInArchive.Open())
                    {
                        using (var fileToCompressStream = new MemoryStream(renderer.ToArray()))
                        {
                            fileToCompressStream.CopyTo(entryStream);
                        }
                    }
                }
            }

           ///How add archiveByDay to archive
        }
    }
}

此时我卡住了

(未经测试的代码,基本上只是为了演示背后的想法)

尝试以下操作:

//create the parent archive at the top of the loop
//with the given code it would have been just 1 archive in 1 archive
//now it can be many archives in 1 archive
//write the archive to file system instead of in memory
using (var archive = new ZipArchive(File.Create("C:\test\test.zip"), ZipArchiveMode.Create, true))
{
    foreach (var (day, _messages) in messages.GroupBy(x => x.Date).ToDictionary(x => x.Key, x => x.ToList()))
    {
        //move the memorystrem to the inner loop
        using (var memoryStream = new MemoryStream())
        {
            using (var archiveByDay = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
            {
                foreach (var message in _messages)
                {
                    var fileInArchive = archiveByDay.CreateEntry($"{message.FileName}", CompressionLevel.Fastest);
                    var renderer = XmlHelper.SerializeWin1251(message);

                    using (var entryStream = fileInArchive.Open())
                    using (var fileToCompressStream = new MemoryStream(renderer.ToArray()))
                        fileToCompressStream.CopyTo(entryStream);
                }
            }

            //flush and set position to 0 enable reading the content that got written to the memory stream
            memoryStream.Flush();
            memoryStream.Position = 0;

            //createentry for the parent archive and write the memory stream to it
            var fileInParentArchive = archive.CreateEntry($"{Guid.NewGuid():D}", CompressionLevel.Fastest);
            using (var entryStream = fileInParentArchive.Open())
            using (var fileToCompressStream = new MemoryStream(memoryStream.ToArray()))
                fileToCompressStream.CopyTo(entryStream);
        }
    }
}