How to compress multiple files in zip file

17,112

Solution 1

Your code is actually saving two separate zip archives to the zip.zip file (a new ZipArchive is created for each file to be compressed). The first zip archive contains only file1.txt, the second only file2.txt. When you open zip.zip in Windows Explorer, it shows just the contents of the second zip archive.

To create a single zip archive containing both files, just move the creation of the ZipArchive outside of your fileList loop:

using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{
    foreach (var file in fileList)
    {                    
        var demoFile = archive.CreateEntry(file.Key);

        using (var entryStream = demoFile.Open())
        using (var b = new BinaryWriter(entryStream))
        {
            b.Write(file.Value);
        }
    }
}

Solution 2

At first glance, I would suggest that your foreach statement around the using var (archive = new ZipArchive...) is the wrong way round.

This way you are creating a new ZipArchive each time you iterate the foreach loop.

Surely you want to create the ZipArchive and loop through the foreach inside of that?

Like this:

private void CompressToZip(string fileName, Dictionary<string, byte[]> fileList)
{
    using (var memoryStream = new MemoryStream())
    {
        using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
        {
            foreach (var file in fileList)
            {   
                var demoFile = archive.CreateEntry(file.Key);

                using (var entryStream = demoFile.Open())
                using (var b = new BinaryWriter(entryStream))
                {
                    b.Write(file.Value);
                }
            }
        }

        using (var fileStream = new FileStream(fileName, FileMode.Create))
        {
            memoryStream.Seek(0, SeekOrigin.Begin);
            memoryStream.CopyTo(fileStream);
        }
    }
}

Hope this helps!

Share:
17,112
Dayan
Author by

Dayan

Updated on June 19, 2022

Comments

  • Dayan
    Dayan almost 2 years

    I'm trying to compress two text files to a zip file. This is how my public method looks like:

    public ActionResult Index()
    {
    
        byte[] file1 = System.IO.File.ReadAllBytes(@"C:\file1.txt");
        byte[] file2 = System.IO.File.ReadAllBytes(@"C:\file2.txt");
        Dictionary<string, byte[]> fileList = new Dictionary<string, byte[]>();
        fileList.Add("file1.txt", file1);
        fileList.Add("file2.txt", file2);
        CompressToZip("zip.zip", fileList);
    
        return View();
    }
    

    This is how my compress method looks like:

    private void CompressToZip(string fileName, Dictionary<string, byte[]> fileList)
    {
        using (var memoryStream = new MemoryStream())
        {
            foreach (var file in fileList)
            {
                using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
                {
                    var demoFile = archive.CreateEntry(file.Key);
    
                    using (var entryStream = demoFile.Open())
                    using (var b = new BinaryWriter(entryStream))
                    {
                        b.Write(file.Value);
                    }
                }
            }
    
            using (var fileStream = new FileStream(fileName, FileMode.Create))
            {
                memoryStream.Seek(0, SeekOrigin.Begin);
                memoryStream.CopyTo(fileStream);
            }
        }
    
    }
    

    In this approach, the zip folder is perfectly created. However the issue is I'm getting only one file inside the zip folder (Just the second file will be created inside the zip folder). There are no errors found.

    Question: How to compress both text files into the zip folder?

    Thank you in advanced!