Unpack a Zip with full control over the operation - icsharpcode/SharpZipLib GitHub Wiki
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.
C#
using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;
public void ExtractZipFile(string archivePath, string password, string outFolder) {
using(var fsInput = File.OpenRead(archivePath))
using(var zf = new ZipFile(fsInput)){
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, fsOutput , buffer);
}
}
}
}
Visual Basic
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