Unpack a zip using ZipInputStream - icsharpcode/SharpZipLib GitHub Wiki
Code Reference / Zip Samples / Unpack a zip using ZipInputStream
The ZipInputStream has one major advantage over using ZipFile to read a zip: it can read from an unseekable input stream - such as a WebClient download. However it currently cannot decode AES encrypted zips.
C#
// Calling example:
using(var data = new WebClient().OpenRead("http://www.example.com/test.zip")){
// This stream cannot be opened with the ZipFile class because CanSeek is false.
UnzipFromStream(data, @"c:\temp");
}
public void UnzipFromStream(Stream zipStream, string outFolder)
{
using(var zipInputStream = new ZipInputStream(zipStream))
{
while (zipInputStream.GetNextEntry() is ZipEntry zipEntry)
{
var entryFileName = zipEntry.Name;
// To remove the folder from the entry:
//var 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.
// 4K is optimum
var buffer = new byte[4096];
// 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);
// Skip directory entry
if (Path.GetFileName(fullZipToPath).Length == 0)
{
continue;
}
// 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 (FileStream streamWriter = File.Create(fullZipToPath))
{
StreamUtils.Copy(zipInputStream, streamWriter, buffer);
}
}
}
}
Visual Basic
' Calling example:
Dim webClient As new WebClient()
Dim data As Stream = webClient.OpenRead("http://www.example.com/test.zip")
' This stream cannot be opened with the ZipFile class because CanSeek is false.
UnzipFromStream(data, "c:\temp")
Public Sub UnzipFromStream(zipStream As Stream, outFolder As String)
Dim zipInputStream As New ZipInputStream(zipStream)
Dim zipEntry As ZipEntry = zipInputStream.GetNextEntry()
While zipEntry IsNot Nothing
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
' 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(zipInputStream, streamWriter, buffer)
End Using
zipEntry = zipInputStream.GetNextEntry()
End While
End Sub