Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I merge 2 zip files into 1?

Tags:

c#

zip

unzip

i have 2 zip files (zip1 and zip2), i need merge this files in one, how can i solve it? I understand that I can fix it decompressing ZIP1 to a temp folder and then add it to zip2, but i think it is inefficient, what is the faster method?

I'm using System.IO.Compression library...

I use this code to explore Zip2:

 using (ZipArchive archive = ZipFile.OpenRead(Zip2))
 {
    foreach (ZipArchiveEntry entry in archive.Entries)
    {
       /*...*/
    }
 }

PD/: The Zip1 and Zip2 files have FILES, FOLDERS AND SUBFOLDERS

like image 301
Manux22 Avatar asked Oct 19 '25 13:10

Manux22


2 Answers

I haven't really tested this, but you can give it a try:

    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;
            }
        }
    }
like image 146
Chief Wiggum Avatar answered Oct 22 '25 03:10

Chief Wiggum


I had an equivalent problem. The zip files came from another process as byte arrays. This method adds their contents to an existing 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);
                            }
                        }
                    }
                }
            }
        }

There does not appear to be any way to directly move a ZipArchiveEntry from one ZipArchive to another, so I resorted to unpacking the source and repacking it to the target via the copy operation.

If you already have a ZipArchive as source, you wouldn't need the MemoryStream zippedSourceStream and could modify the code to use sourceArchive directly as the method parameter.

like image 29
Christopher Hamkins Avatar answered Oct 22 '25 02:10

Christopher Hamkins



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!