How To Extract A Zip File With C#

The .Net Framework Class Libraries are great and allow you to manipulate many different file formats. Unfortunately they seemed to have left out support for standard Zip files. Thankfully our good friends over at ICSharpCode have released an awesome little library for handling Zip files called the SharpZipLib.

The library is very simple to use and supports several formats including:

  • Zip
  • GZip
  • Tar
  • BZip2

Using SharpZipLib

Extracting a file with SharpZipLib is really quite simple. First you create a ZipInputStream from an existing FileStream to the zip file.

ZipInputStream zinstream = new ZipInputStream(File.OpenRead(source));

Next you read the entries from the zip file, which could be either a file or directory.

ZipEntry theEntry;
 
while ((theEntry = zinstream.GetNextEntry()) != null)
{
   // if theEntry is a directory then create it on disk
   // otherwise it’s a file so read from zinstream just like
   // you would any other file
}

The ZipEntry represents either a file or directory that must be read and reproduced in the target directory where you are extracting the files to. GetNextEntry will continue to return either the next directory or the next file in the Zip file until no more exist. Here is a complete example of extracting all files (while maintaining directory structure) to a local folder.

The Extraction Function

        public static int ExtractAll(string source, string destination)
        {
            ZipInputStream zinstream = null; // used to read from the zip file
            int numFileUnzipped = 0; // number of files extracted from the zip file
 
            try
            {
                // create a zip input stream from source zip file
                zinstream = new ZipInputStream(File.OpenRead(source));
 
                // we need to extract to a folder so we must create it if needed
                if (Directory.Exists(destination) == false)
                    Directory.CreateDirectory(destination);
 
                ZipEntry theEntry; // an entry in the zip file which could be a file or directory
 
                // now, walk through the zip file entries and copy each file/directory
                while ((theEntry = zinstream.GetNextEntry()) != null)
                {
                    string dirname = Path.GetDirectoryName(theEntry.Name); // the file path
                    string fname   = Path.GetFileName(theEntry.Name);      // the file name
 
                    // if a path name exists we should create the directory in the destination folder
                    string target = destination + Path.DirectorySeparatorChar + dirname;
                    if (dirname.Length > 0 && !Directory.Exists(target)) 
                        Directory.CreateDirectory(target);
 
                    // now we know the proper path exists in the destination so copy the file there
                    if (fname != String.Empty)
                    {
                        DecompressAndWriteFile(destination + Path.DirectorySeparatorChar + theEntry.Name, zinstream);
                        numFileUnzipped++;
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                zinstream.Close();
            }
 
            return numFileUnzipped;
        }

And the DecompressAndWrite method:

        private static void DecompressAndWriteFile( string destination, ZipInputStream source )
        {
            FileStream wstream = null;
 
            try
            {
                // create a stream to write the file to
                wstream = File.Create(destination);
 
                const int block = 2048; // number of bytes to decompress for each read from the source
 
                byte[] data = new byte[block]; // location to decompress the file to
 
                // now decompress and write each block of data for the zip file entry
                while (true)
                {
                    int size = source.Read(data, 0, data.Length);
 
                    if (size > 0)
                        wstream.Write(data, 0, size);
                    else
                        break; // no more data
                }
            }
            catch(Exception)
            {
                throw;
            }
            finally
            {
                if( wstream != null )
                    wstream.Close();
            }
        }

Pretty neat huh? I love how simple it is.
If those methods are placed into a class called Zip, then extracting a Zip file is as easy as:

Zip.ExtractAll(myZipFile, myDestinationFolder);

I’ve put together a sample project that uses the SharpZipLib to extract the contents of a zip file. It basically just allows you to select the zip file and the destination from a form and uses the methods above. You can find it below.

DOWNLOAD SAMPLE APPLICATION

Let me know if you find this useful or need any help!!!

April 3, 2009   Posted in: General

One Response

  1. Extracting Zip Files « Query On .net - January 21, 2010

    [...] 21, 2010 Below is useful link to extract zip files with the use of SharpZipLib Extract Zip File Once file extracted you can delete the zip file using [...]

Leave a Reply