Skip to content

Unpack a Zip with full control over the operation

nils måsén edited this page Aug 21, 2019 · 6 revisions

Code Reference / Zip Samples / Unpack a Zip with full control over the operation

This sample illustrates many aspects:

  • skipping directory entries
  • controlling the folder where the output is placed
  • passwords
  • exception handling, closing disk files, and efficient use of memory.

While this example is purely disk files, scroll down where other inputs and outputs such as memory stream are covered.

using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;

public void ExtractZipFile(string archiveFilenameIn, string password, string outFolder) {

    using(Stream fsInput = File.OpenRead(archiveFilenameIn)) 
    using(zf = new ZipFile(fs)){
    if (!String.IsNullOrEmpty(password)) {
        // AES encrypted entries are handled automatically
        zf.Password = password;
    }
    foreach (ZipEntry zipEntry in zf) {
        if (!zipEntry.IsFile) {
            // Ignore directories
            continue;
        }
        String entryFileName = zipEntry.Name;
        // to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName);
        // Optionally match entrynames against a selection list here to skip as desired.
        // The unpacked length is available in the zipEntry.Size property.		

        // Manipulate the output filename here as desired.
        var fullZipToPath = Path.Combine(outFolder, entryFileName);
        var directoryName = Path.GetDirectoryName(fullZipToPath);
        if (directoryName.Length > 0) {
            Directory.CreateDirectory(directoryName);
        }

        // 4K is optimum
        var buffer = new byte[4096];

        // Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size
        // of the file, but does not waste memory.
        // The "using" will close the stream even if an exception occurs.
        using(var zipStream = zf.GetInputStream(zipEntry))
        using (Stream fsOutput = File.Create(fullZipToPath)) {
            StreamUtils.Copy(zipStream, streamWriter, buffer);
        }
	}
}
Imports ICSharpCode.SharpZipLib.Core
Imports ICSharpCode.SharpZipLib.Zip

Public Sub ExtractZipFile(archiveFilenameIn As String, password As String, outFolder As String)
	Dim zf As ZipFile = Nothing
	Try
		Dim fs As FileStream = File.OpenRead(archiveFilenameIn)
		zf = New ZipFile(fs)
		If Not [String].IsNullOrEmpty(password) Then	' AES encrypted entries are handled automatically
			zf.Password = password
		End If
		For Each zipEntry As ZipEntry In zf
			If Not zipEntry.IsFile Then		' Ignore directories
				Continue For
			End If
			Dim entryFileName As [String] = zipEntry.Name
			' to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName);
			' Optionally match entrynames against a selection list here to skip as desired.
			' The unpacked length is available in the zipEntry.Size property.

			Dim buffer As Byte() = New Byte(4095) {}	' 4K is optimum
			Dim zipStream As Stream = zf.GetInputStream(zipEntry)

			' Manipulate the output filename here as desired.
			Dim fullZipToPath As [String] = Path.Combine(outFolder, entryFileName)
			Dim directoryName As String = Path.GetDirectoryName(fullZipToPath)
			If directoryName.Length > 0 Then
				Directory.CreateDirectory(directoryName)
			End If

			' Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size
			' of the file, but does not waste memory.
			' The "Using" will close the stream even if an exception occurs.
			Using streamWriter As FileStream = File.Create(fullZipToPath)
				StreamUtils.Copy(zipStream, streamWriter, buffer)
			End Using
		Next
	Finally
		If zf IsNot Nothing Then
			zf.IsStreamOwner = True		' Makes close also shut the underlying stream
			' Ensure we release resources
			zf.Close()
		End If
	End Try
End Sub
Clone this wiki locally