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);
}
}
}