How to create/extract ZIP files in .NET with #ziplib

Please let our ADS show!

This sites offers only FREE software and it's supported by a few advertisement boxes (no intrusive popups).
Please:

  • disable your AdBlocker by adding CoolSoft website to whitelist
  • give the proper cookie consent
  • enable JavaScript for this website

This seconds wait is to let you update your browser configuration...

Ok, I've done the required changes... now show me your content!
!!! Please enable JavaScript !!!

Some years ago I published an article explaining how to use #ziplib to compress files in a ZIP archive.

#ziplib is an open source .NET library to manager ZIP, TAR.GZ, TAR.BZ2 and other type of compressed archives.
It comes from the same guys of SharpDevelop.

That article was created when VS2003 was the state of art; it is still working and I still receive positive feedbacks about it.
Anyway it misses a part that was left to the reader: the extraction from a pre-existing ZIP.

Well, now it's time to refresh that article, translate it in English, add the missing part and provide a working (downloadable) sample.

ZIP file creation

Create a compressed ZIP archive is like writing to a file stream; #ziplib provides a compressed output stream which can be used for this.
Each file inside the archive must be "marked" since ZIP archive must take note of its start and end (filename, size, date and so on).

Let's see relevant parts. Full sample code is available at the end of this page.

First of all, we need to create a compressed stream

' stream di scrittura dello ZIP
Dim strmZipOutputStream As New ZipOutputStream(File.Create("c:\prova.zip"))

Then we need a CRC32 class to calculate ZIP checksum

' classe per il calcolo del CRC32
Dim objCrc32 As New Crc32

ZipOutputStream object allows to choose the desired compression level. Value 7 is a good compromise between space and speed

strmZipOutputStream.SetLevel(7)

Now we are ready to add zip content; each file in a #ziplib ZIP archive is described by a ZipEntry class

' ZIP file new entry
Dim objZipEntry As ZipEntry = New ZipEntry(filename)

Suppose SourceFiles is a list with source filenames; let's traverse this list and add each file

' traverse the list with source filenames
For Each fileName As String In SourceFiles
 
     ' new ZIP entry
     Dim newZIPEntry As ZipEntry = New ZipEntry(System.IO.Path.GetFileName(fileName))
 
     ' open a stream
     Dim strmFile As FileStream = File.OpenRead(fileName)
 
     ' reset CRC
     objCrc32.Reset()
 
     ' add new entry into ZIP archive
     strmZipOutputStream.PutNextEntry(newZIPEntry)
 
     ' read source file
     While strmFile.Position < strmFile.Length
         bytesRead = strmFile.Read(mBuffer, 0, mBuffer.Length)
         strmZipOutputStream.Write(mBuffer, 0, bytesRead)
         objCrc32.Update(mBuffer, 0, bytesRead)
     End While
 
     ' set CRC value of the entry
     newZIPEntry.Crc = objCrc32.Value
 
     ' set new entry attributes
     newZIPEntry.DateTime = File.GetCreationTime(fileName)
     newZIPEntry.Size = strmFile.Length
 
     ' close source file
     strmFile.Close()
 
Next

ZIP file extraction

This part is very similar to the previous one.
ziplib provides an input compressed stream; we must open it for reading.
Since the ZIP archive is a single, continuous file, each contained item (compressed file) can be obtained by asking #ziplib to set stream boundaries around it.

Let's see relevant parts. Full sample code is available at the end of this page.

First of all let's open the compressed input file stream

' input ZIP stream
Dim strmZipInputStream As New ZipInputStream(File.OpenRead(ZipFileName))

Then traverse its entries (remember ZipEntry class?) and extract them one by one

Do
  ' read next file
  Dim entry As ZipEntry = strmZipInputStream.GetNextEntry()
  If entry Is Nothing Then Exit Do
  ' open output file
  Dim bytesRead As Integer
  Dim out As FileStream = File.Create(Path.Combine(DestPath, entry.Name))
  ' read input ZIP archive
  Do bytesRead = strmZipInputStream.Read(mBuffer, 0, mBuffer.Length)
    If bytesRead = 0 Then Exit Do
    out.Write(mBuffer, 0, bytesRead)
  Loop
  ' close file
  out.Close()
Loop

Note the call to .GetNextEntry: it asks the underlying stream to move to next entry start point and reads out entry details, like filename, dates and attributes.

You're done.

Please note that this code is really simple, it doesn't include error checking and fool-prof tests. Its intent is only to be a quick start for using #ziplib library so you must extend it to your needs.