如何将 2 个 zip 文件合并为 1 个?
How can I merge 2 zip files into 1?
我有 2 个 zip 文件(zip1 和 zip2),我需要将这些文件合并为一个,我该如何解决?
我知道我可以修复它解压 ZIP1 到一个临时文件夹,然后将它添加到 zip2,但我认为它效率低下,更快的方法是什么?
我正在使用 System.IO.Compression
库...
我使用这段代码探索 Zip2:
using (ZipArchive archive = ZipFile.OpenRead(Zip2))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
/*...*/
}
}
PD/:Zip1 和 Zip2 文件有 个文件、文件夹和子文件夹
我还没有真正测试过这个,但你可以试一试:
public ZipArchive Merge(List<ZipArchive> archives)
{
if (archives == null) throw new ArgumentNullException("archives");
if (archives.Count == 1) return archives.Single();
using (var memoryStream = new MemoryStream())
{
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{
foreach (var zipArchive in archives)
{
foreach (var zipArchiveEntry in zipArchive.Entries)
{
var file = archive.CreateEntry(zipArchiveEntry.FullName);
using (var entryStream = file.Open()) {
using (var streamWriter = new StreamWriter(entryStream)) { streamWriter.Write(zipArchiveEntry.Open()); }
}
}
}
return archive;
}
}
}
此示例说明如何在 DotNetZip 库的帮助下将两个 zip 文件合并到内存中的第三个文件或与实际文件合并:
//file1 and file2 are MemoryStream or file names
//for performance reason it is better that file1 is less than file2
//file1.Position = 0;//ensure at case of MemoryStream
using (var zip1 = ZipFile.Read(file1))
{
//file2.Position = 0;//ensure at case of MemoryStream
using (var zip2 = ZipFile.Read(file2))
{
var zip2EntryNames = zip2.Entries.Select(y => y.FileName).ToList();
foreach (var entry in zip1.Entries.Where(x => !zip2EntryNames.Contains(x.FileName)).ToList())
{
var memoryStream = new MemoryStream();
entry.Extract(memoryStream);
memoryStream.Position = 0;
zip2.AddEntry(entry.FileName, memoryStream);
}
if(save2file)
zip2.Save(fileNameResult);
else
using (var result = new MemoryStream())
{
zip2.Save(result);
}
}
}
我遇到了同样的问题。 zip 文件作为字节数组来自另一个进程。此方法将它们的内容添加到现有的 ZipArchive。
using System.IO;
using System.IO.Compression;
/// <summary>
/// Copies the contents of a zip "file" represented as a byte array
/// to the given ZipArchive.
/// </summary>
/// <param name="targetArchive">The archive to which to add the entries.</param>
/// <param name="zippedSourceBuffer">The source data as zip "file" in a byte array.</param>
public static void addZipBufferToZipArchive(ZipArchive targetArchive, byte[] zippedSourceBuffer)
{
using (MemoryStream zippedSourceStream = new MemoryStream(zippedSourceBuffer))
{
using (ZipArchive sourceArchive = new ZipArchive(zippedSourceStream))
{
foreach (ZipArchiveEntry sourceEntry in sourceArchive.Entries)
{
ZipArchiveEntry targetEntry = targetArchive.CreateEntry(sourceEntry.FullName);
using (Stream targetEntryStream = targetEntry.Open())
{
using (Stream sourceStream = sourceEntry.Open())
{
sourceStream.CopyTo(targetEntryStream);
}
}
}
}
}
}
似乎没有任何方法可以将 ZipArchiveEntry 从一个 ZipArchive 直接移动到另一个 ZipArchive,因此我求助于解压缩源并通过复制操作将其重新打包到目标。
如果您已经将 ZipArchive 作为源,则不需要 MemoryStream zippedSourceStream 并且可以修改代码以直接使用 sourceArchive 作为方法参数。
我有 2 个 zip 文件(zip1 和 zip2),我需要将这些文件合并为一个,我该如何解决? 我知道我可以修复它解压 ZIP1 到一个临时文件夹,然后将它添加到 zip2,但我认为它效率低下,更快的方法是什么?
我正在使用 System.IO.Compression
库...
我使用这段代码探索 Zip2:
using (ZipArchive archive = ZipFile.OpenRead(Zip2))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
/*...*/
}
}
PD/:Zip1 和 Zip2 文件有 个文件、文件夹和子文件夹
我还没有真正测试过这个,但你可以试一试:
public ZipArchive Merge(List<ZipArchive> archives)
{
if (archives == null) throw new ArgumentNullException("archives");
if (archives.Count == 1) return archives.Single();
using (var memoryStream = new MemoryStream())
{
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{
foreach (var zipArchive in archives)
{
foreach (var zipArchiveEntry in zipArchive.Entries)
{
var file = archive.CreateEntry(zipArchiveEntry.FullName);
using (var entryStream = file.Open()) {
using (var streamWriter = new StreamWriter(entryStream)) { streamWriter.Write(zipArchiveEntry.Open()); }
}
}
}
return archive;
}
}
}
此示例说明如何在 DotNetZip 库的帮助下将两个 zip 文件合并到内存中的第三个文件或与实际文件合并:
//file1 and file2 are MemoryStream or file names
//for performance reason it is better that file1 is less than file2
//file1.Position = 0;//ensure at case of MemoryStream
using (var zip1 = ZipFile.Read(file1))
{
//file2.Position = 0;//ensure at case of MemoryStream
using (var zip2 = ZipFile.Read(file2))
{
var zip2EntryNames = zip2.Entries.Select(y => y.FileName).ToList();
foreach (var entry in zip1.Entries.Where(x => !zip2EntryNames.Contains(x.FileName)).ToList())
{
var memoryStream = new MemoryStream();
entry.Extract(memoryStream);
memoryStream.Position = 0;
zip2.AddEntry(entry.FileName, memoryStream);
}
if(save2file)
zip2.Save(fileNameResult);
else
using (var result = new MemoryStream())
{
zip2.Save(result);
}
}
}
我遇到了同样的问题。 zip 文件作为字节数组来自另一个进程。此方法将它们的内容添加到现有的 ZipArchive。
using System.IO;
using System.IO.Compression;
/// <summary>
/// Copies the contents of a zip "file" represented as a byte array
/// to the given ZipArchive.
/// </summary>
/// <param name="targetArchive">The archive to which to add the entries.</param>
/// <param name="zippedSourceBuffer">The source data as zip "file" in a byte array.</param>
public static void addZipBufferToZipArchive(ZipArchive targetArchive, byte[] zippedSourceBuffer)
{
using (MemoryStream zippedSourceStream = new MemoryStream(zippedSourceBuffer))
{
using (ZipArchive sourceArchive = new ZipArchive(zippedSourceStream))
{
foreach (ZipArchiveEntry sourceEntry in sourceArchive.Entries)
{
ZipArchiveEntry targetEntry = targetArchive.CreateEntry(sourceEntry.FullName);
using (Stream targetEntryStream = targetEntry.Open())
{
using (Stream sourceStream = sourceEntry.Open())
{
sourceStream.CopyTo(targetEntryStream);
}
}
}
}
}
}
似乎没有任何方法可以将 ZipArchiveEntry 从一个 ZipArchive 直接移动到另一个 ZipArchive,因此我求助于解压缩源并通过复制操作将其重新打包到目标。
如果您已经将 ZipArchive 作为源,则不需要 MemoryStream zippedSourceStream 并且可以修改代码以直接使用 sourceArchive 作为方法参数。