如何创建包含文件的 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);
}
}
}
我有很多文件需要归类归档,所有这些归档都需要放入归档中。
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);
}
}
}