Home > Software design >  How to create a zip archive with files and attach it to a zip archive?
How to create a zip archive with files and attach it to a zip archive?

Time:09-16

I have a number of files that need to be grouped into archives, and all these archives need to be put into the 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
        }
    }
}

At this point i'm stuck

CodePudding user response:

(Untested code, basically just to demonstrate the idea behind it)

Try the following:

//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);
        }
    }
}
  • Related