如何将2个zip文件合并为1个?

时间:2015-01-19 23:40:21

标签: c# zip unzip

我有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文件包含文件,文件夹和子文件

3 个答案:

答案 0 :(得分:3)

我还没有真正测试过这个,但你可以尝试一下:

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

答案 1 :(得分:1)

我有一个同样的问题。 zip文件来自另一个进程,为字节数组。此方法将其内容添加到现有的ZipArchive中。

return Json(new { success = true, result = "ViewResult" });

似乎没有任何方法可以将ZipArchiveEntry从一个ZipArchive直接移动到另一个,所以我诉诸于将源拆包并通过复制操作将其重新打包到目标。

如果已经有一个ZipArchive作为源,则不需要MemoryStream zippedSourceStream,并且可以修改代码以将sourceArchive直接用作方法参数。

答案 2 :(得分:0)

此示例显示如何在DotNetZip库的帮助下将两个zip文件合并到内存中的第三个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);                        
            }
    }
}