Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compress multiple files in zip file

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!

like image 866
Dayan Avatar asked May 07 '16 17:05

Dayan


People also ask

Why would you zip compress multiple files?

Zipped (compressed) files take up less storage space and can be transferred to other computers more quickly than uncompressed files. In Windows, you work with zipped files and folders in the same way that you work with uncompressed files and folders.

Can 7 zip unzip multiple files at once?

Let's say there are folders named A, B, C, etc. through Z. Inside each folder are a number of zip files. I can select all the zips in a folder, right click, select 7zip, and select Extract to "*" and it works perfectly.


2 Answers

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);
        }
    }
}
like image 192
Phil Ross Avatar answered Oct 31 '22 11:10

Phil Ross


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!

like image 26
Geoff James Avatar answered Oct 31 '22 11:10

Geoff James