You would have thought that .NET, with its vast libraries would have a decent way to handle Zip compression, but this is sadly not so.

Now C# does allow compression usig GZipStream, which can be used as follows to compress a file

        public void zipFile(FileInfo file)
        {
            FileStream sourceFile = File.OpenRead(file.FullName);
            FileStream destFile = File.Create(file.FullName + ".zip");

            GZipStream stream = new GZipStream(destFile, CompressionMode.Compress);

            try
            {
                int data = sourceFile.ReadByte();
                while (data != -1)
                {
                    stream.WriteByte((byte)data);
                    data = sourceFile.ReadByte();
                }
            }
            finally
            {
                stream.Dispose();
                sourceFile.Close();
                sourceFile.Dispose();
            } 
        }

This produces a compressed file, but it is not exactly compatible with Zip archives, and Windows has quite a bit of a problem opening up this king of archive, so it is not always very useful.

The same thing can be done, using a conventional Zip archive, using the SharpZipLib library, which provides a much richer compression library than what Visual Studio natively provides.

        using System.IO;
        using ICSharpCode.SharpZipLib.Zip;

        public void zipFile(FileInfo file)
        {
            FileStream stream;
            byte[] buffer;
            ZipOutputStream zipStream = new ZipOutputStream(File.Create(file.FullName + ".zip"));
            zipStream.SetLevel(9); 
            ZipEntry zipEntry = new ZipEntry(file.Name);
            zipStream.PutNextEntry(zipEntry);

            stream = File.OpenRead(file.FullName);
            buffer = new byte[stream.Length];
            stream.Read(buffer, 0, buffer.Length);
            zipStream.Write(buffer, 0, buffer.Length);
            
            zipStream.Finish();
            zipStream.Close();
            stream.Close();
        }

How this works is that we create a zip stream which we are going to write the data to. Each file we want to write to the zip file is added to the zip stream by means of a zip entry.

We add the zip entry to the zip stream, and then read the data from the original file, and then write it into the zip stream. Everything else is taken care of behind the scenes when we call the Finish() method of the zip stream.
Unzipping a file is a little more work. but quite straightforward.

        public static void UnZipFiles(string zipFile, string folder)
        {
            ZipInputStream zipStream = new ZipInputStream(File.OpenRead(zipPathAndFile));
            ZipEntry zipEntry;

            while ((zipEntry = zipStream.GetNextEntry()) != null)
            {
                string directory = outputFolder;
                string filename = Path.GetFileName(zipEntry.Name);
                Directory.CreateDirectory(folder);
                if (filename != String.Empty)
                {
                    string fullPath = folder + "/" + zipEntry.Name;
                    string fullDir = Path.GetDirectoryName(fullPath);
                    if (!Directory.Exists(fullDir))
                    {
                        Directory.CreateDirectory(fullDir);
                    }
                    FileStream streamWriter = File.Create(fullPath);
                    int size = 2048;
                    byte[] data = new byte[2048];
                    while (true)
                    {
                        size = zipStream.Read(data, 0, data.Length);
                        if (size > 0)
                        {
                            streamWriter.Write(data, 0, size);
                        }
                        else
                        {
                            break;
                        }
                    }
                    streamWriter.Close();
                }
            }
            zipStream.Close();
        }

Unzipping a zip file is simply the reverse of the zipping operation.

Share