0

I have a byte[] of a zip file. I need to unzip the file in memory and find "dist" folder inside the zip (there will be always a dist folder) and create a new zip file with whatever inside that "dist" folder.

"dist" folder could have files and sub-folders in it. I need the new zip file in byte[] so there will be in memory ONLY operation and no access to physical disk.

i try to use "SharpZipLib" no luck. i'm using .net core 2.0

Brad Kiani
  • 271
  • 1
  • 9
  • 20

1 Answers1

7

please try below code

   using (MemoryStream srcMemoryStream = new MemoryStream())
        {
            using (MemoryStream targetMemoryStream = new MemoryStream())
            {
                // to have a byte array, I just read a file and store it into a memory stream
                using (FileStream sourceZipFile = new FileStream(@"f:\source-file.zip", FileMode.Open))
                {
                    sourceZipFile.CopyTo(srcMemoryStream);
                }

                using (ZipArchive srcArchive = new ZipArchive(srcMemoryStream, ZipArchiveMode.Read))
                {
                    using (ZipArchive destArchive = new ZipArchive(targetMemoryStream, ZipArchiveMode.Create, true))
                    {

                        srcArchive.Entries
                            .Where(entry => entry.FullName.Contains("dist/"))
                            .ToList()
                            .ForEach((entry) =>
                            {
                                // i simply create the same folder with the same structure in other archive
                                // if you want to change the structure, you have to rename or remove parts of 
                                // the path like below
                                ///  var newEntryName = entry.FullName.Replace("files/dist/", "new-dist/");
                                ///  ZipArchiveEntry newEntry = destArchive.CreateEntry(newEntryName);
                                ZipArchiveEntry newEntry = destArchive.CreateEntry(entry.FullName);
                                using (Stream srcEntry = entry.Open())
                                {
                                    using (Stream destEntry = newEntry.Open())
                                    {
                                        srcEntry.CopyTo(destEntry);
                                    }
                                }
                            });
                    }
                }

                // i just write the zip file on disk to make sure that it works, your desire state is already achieved
                // before this line of code, and the result byte Array is inside the targetMemoryStream memory stream
                using (FileStream fs = new FileStream(@"f:/destination-file.zip", FileMode.Create))
                {
                    targetMemoryStream.WriteTo(fs);
                    targetMemoryStream.Flush();
                    fs.Flush(true);
                }

            }
        }

you can store those byte arrays in the memory stream, I just read a file and store it into a memory stream but you can simply use below code:

MemoryStream srcMemoryStream = new MemoryStream();
srcMemoryStream.Write(byteArray, 0, byteArray.Length);
  • that's working thanks, just one thing, the new zip got a dist folder in it. How can I put dist folder items in the root of zip folder – Brad Kiani Dec 10 '18 at 04:55
  • 1
    you're welcome, please read the comment, I already mentioned that point in the comment. if you want to remove a part of the path just replace it with string empty => var newEntryName = entry.FullName.Replace("dist/", string.Empty); – Mohammad Khodabandeh Dec 10 '18 at 06:19