SharZipLib 例子

http://wiki.sharpdevelop.net/SharpZipLib-Zip-Samples.ashx


How to use SharpZipLib to work with Zip files

These samples try to cover the range of situations you will encounter.You may need to combine parts of each sample for your application.


Create a Zip with full control over contents

This sample illustrates many aspects:
  • multiple entries
  • entry name correction
  • passwords and encryption options
  • Zip64 format issues.

While this example is purely disk files, the next following example shows how to use memory stream for input and output.

C#
using System;
using System.IO;
using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;

// Compresses the files in the nominated folder, and creates a zip file on disk named as outPathname.
//
public void CreateSample(string outPathname, string password, string folderName) {

	FileStream fsOut = File.Create(outPathname);
	ZipOutputStream zipStream = new ZipOutputStream(fsOut);

	zipStream.SetLevel(3); //0-9, 9 being the highest level of compression

	zipStream.Password = password;	// optional. Null is the same as not setting.

	// This setting will strip the leading part of the folder path in the entries, to
	// make the entries relative to the starting folder.
	// To include the full path for each entry up to the drive root, assign folderOffset = 0.
	int folderOffset = folderName.Length + (folderName.EndsWith("\\") ? 0 : 1);

	CompressFolder(folderName, zipStream, folderOffset);

	zipStream.IsStreamOwner = true;	// Makes the Close also Close the underlying stream
	zipStream.Close();
}

// Recurses down the folder structure
//
private void CompressFolder(string path, ZipOutputStream zipStream, int folderOffset) {

	string[] files = Directory.GetFiles(path);

	foreach (string filename in files) {

		FileInfo fi = new FileInfo(filename);

		string entryName = filename.Substring(folderOffset); // Makes the name in zip based on the folder
		entryName = ZipEntry.CleanName(entryName); // Removes drive from name and fixes slash direction
		ZipEntry newEntry = new ZipEntry(entryName);
		newEntry.DateTime = fi.LastWriteTime; // Note the zip format stores 2 second granularity

		// Specifying the AESKeySize triggers AES encryption. Allowable values are 0 (off), 128 or 256.
		//   newEntry.AESKeySize = 256;

		// To permit the zip to be unpacked by built-in extractor in WinXP and Server2003, WinZip 8, Java, and other older code,
		// you need to do one of the following: Specify UseZip64.Off, or set the Size.
		// If the file may be bigger than 4GB, or you do not need WinXP built-in compatibility, you do not need either,
		// but the zip will be in Zip64 format which not all utilities can understand.
		//   zipStream.UseZip64 = UseZip64.Off;
		newEntry.Size = fi.Length;

		zipStream.PutNextEntry(newEntry);

		// Zip the file in buffered chunks
		// the "using" will close the stream even if an exception occurs
		byte[ ] buffer = new byte[4096];
		using (FileStream streamReader = File.OpenRead(filename)) {
			StreamUtils.Copy(streamReader, zipStream, buffer);
		}
		zipStream.CloseEntry();
	}
	string[ ] folders = Directory.GetDirectories(path);
	foreach (string folder in folders) {
		CompressFolder(folder, zipStream, folderOffset);
	}
}

VB
Imports System
Imports System.IO
Imports ICSharpCode.SharpZipLib.Core
Imports ICSharpCode.SharpZipLib.Zip

' Compresses the files in the nominated folder, and creates a zip file on disk named as outPathname.
'
Public Sub CreateSample(outPathname As String, password As String, folderName As String)

	Dim fsOut As FileStream = File.Create(outPathname)
	Dim zipStream As New ZipOutputStream(fsOut)

	zipStream.SetLevel(3)		'0-9, 9 being the highest level of compression
	zipStream.Password = password	' optional. Null is the same as not setting.

	' This setting will strip the leading part of the folder path in the entries, to
	' make the entries relative to the starting folder.
	' To include the full path for each entry up to the drive root, assign folderOffset = 0.
	Dim folderOffset As Integer = folderName.Length + (If(folderName.EndsWith("\"), 0, 1))

	CompressFolder(folderName, zipStream, folderOffset)

	zipStream.IsStreamOwner = True
	' Makes the Close also Close the underlying stream
	zipStream.Close()
End Sub

' Recurses down the folder structure
'
Private Sub CompressFolder(path As String, zipStream As ZipOutputStream, folderOffset As Integer)

	Dim files As String() = Directory.GetFiles(path)

	For Each filename As String In files

		Dim fi As New FileInfo(filename)

		Dim entryName As String = filename.Substring(folderOffset)	' Makes the name in zip based on the folder
		entryName = ZipEntry.CleanName(entryName)		' Removes drive from name and fixes slash direction
		Dim newEntry As New ZipEntry(entryName)
		newEntry.DateTime = fi.LastWriteTime			' Note the zip format stores 2 second granularity

		' Specifying the AESKeySize triggers AES encryption. Allowable values are 0 (off), 128 or 256.
		'   newEntry.AESKeySize = 256;

		' To permit the zip to be unpacked by built-in extractor in WinXP and Server2003, WinZip 8, Java, and other older code,
		' you need to do one of the following: Specify UseZip64.Off, or set the Size.
		' If the file may be bigger than 4GB, or you do not need WinXP built-in compatibility, you do not need either,
		' but the zip will be in Zip64 format which not all utilities can understand.
		'   zipStream.UseZip64 = UseZip64.Off;
		newEntry.Size = fi.Length

		zipStream.PutNextEntry(newEntry)

		' Zip the file in buffered chunks
		' the "using" will close the stream even if an exception occurs
		Dim buffer As Byte() = New Byte(4095) {}
		Using streamReader As FileStream = File.OpenRead(filename)
			StreamUtils.Copy(streamReader, zipStream, buffer)
		End Using
		zipStream.CloseEntry()
	Next
	Dim folders As String() = Directory.GetDirectories(path)
	For Each folder As String In folders
		CompressFolder(folder, zipStream, folderOffset)
	Next
End Sub

Create a Zip from/to a memory stream or byte array

This sample concentrates on the differences for memorystream output, the most important of which is setting IsStreamOwner = false so that the Close (which is needed to finish up the output) does not close the underlying memorystream.For multiple entries, passwords, etc, see the code sample above.

C#
using ICSharpCode.SharpZipLib.Zip;

// Compresses the supplied memory stream, naming it as zipEntryName, into a zip,
// which is returned as a memory stream or a byte array.
//
public MemoryStream CreateToMemoryStream(MemoryStream memStreamIn, string zipEntryName) {

	MemoryStream outputMemStream = new MemoryStream();
	ZipOutputStream zipStream = new ZipOutputStream(outputMemStream);

	zipStream.SetLevel(3); //0-9, 9 being the highest level of compression

	ZipEntry newEntry = new ZipEntry(zipEntryName);
	newEntry.DateTime = DateTime.Now;

	zipStream.PutNextEntry(newEntry);

	StreamUtils.Copy(memStreamIn, zipStream, new byte[4096]);
	zipStream.CloseEntry();

	zipStream.IsStreamOwner = false;	// False stops the Close also Closing the underlying stream.
	zipStream.Close();			// Must finish the ZipOutputStream before using outputMemStream.

	outputMemStream.Position = 0;
	return outputMemStream;

	// Alternative outputs:
	// ToArray is the cleaner and easiest to use correctly with the penalty of duplicating allocated memory.
	byte[] byteArrayOut = outputMemStream.ToArray();

	// GetBuffer returns a raw buffer raw and so you need to account for the true length yourself.
	byte[] byteArrayOut = outputMemStream.GetBuffer();
	long len = outputMemStream.Length;
}

VB
Imports ICSharpCode.SharpZipLib.Zip

' Compresses the supplied memory stream, naming it as zipEntryName, into a zip,
' which is returned as a memory stream or a byte array.
'
Public Function CreateToMemoryStream(memStreamIn As MemoryStream, zipEntryName As String) As MemoryStream

	Dim outputMemStream As New MemoryStream()
	Dim zipStream As New ZipOutputStream(outputMemStream)

	zipStream.SetLevel(3)		'0-9, 9 being the highest level of compression
	Dim newEntry As New ZipEntry(zipEntryName)
	newEntry.DateTime = DateTime.Now

	zipStream.PutNextEntry(newEntry)

	StreamUtils.Copy(memStreamIn, zipStream, New Byte(4095) {})
	zipStream.CloseEntry()

	zipStream.IsStreamOwner = False		' False stops the Close also Closing the underlying stream.
	zipStream.Close()			' Must finish the ZipOutputStream before using outputMemStream.
	outputMemStream.Position = 0
	Return outputMemStream

	' Alternative outputs:
	' ToArray is the cleaner and easiest to use correctly with the penalty of duplicating allocated memory.
	Dim byteArrayOut As Byte() = outputMemStream.ToArray()

	' GetBuffer returns a raw buffer raw and so you need to account for the true length yourself.
	Dim byteArrayOut As Byte() = outputMemStream.GetBuffer()
	Dim len As Long = outputMemStream.Length
End Function

Create a Zip as a browser download attachment in IIS

This sample creates a zip as a browser download.

By writing directly to the Response OutputStream, zip download starts immediately, which fixes timeout problems when zipping large files.

For inputting from a memorystream instead of disk files, or passwording etc, see the samples above.

C#
// the aspx page has just one line e.g. <%@ Page language="c#" Codebehind=...
// but if you must run this from within a page that has other output, start with a Response.Clear();

using ICSharpCode.SharpZipLib.Zip;

// This will accumulate each of the files named in the fileList into a zip file,
// and stream it to the browser.
// This approach writes directly to the Response OutputStream.
// The browser starts to receive data immediately which should avoid timeout problems.
// This also avoids an intermediate memorystream, saving memory on large files.
//
private void DownloadZipToBrowser(List <string> zipFileList) {

	Response.ContentType = "application/zip";
	// If the browser is receiving a mangled zipfile, IIS Compression may cause this problem. Some members have found that
	//    Response.ContentType = "application/octet-stream"     has solved this. May be specific to Internet Explorer.

	Response.AppendHeader("content-disposition", "attachment; filename=\"Download.zip\"");
	response.CacheControl = "Private";
	response.Cache.SetExpires(DateTime.Now.AddMinutes(3)); // or put a timestamp in the filename in the content-disposition

	byte[] buffer = new byte[4096];

	ZipOutputStream zipOutputStream = new ZipOutputStream(Response.OutputStream);
	zipOutputStream.SetLevel(3); //0-9, 9 being the highest level of compression

	foreach (string fileName in zipFileList) {

		Stream fs = File.OpenRead(fileName);	// or any suitable inputstream

		ZipEntry entry = new ZipEntry(ZipEntry.CleanName(fileName));
		entry.Size = fs.Length;
		// Setting the Size provides WinXP built-in extractor compatibility,
		//  but if not available, you can set zipOutputStream.UseZip64 = UseZip64.Off instead.

		zipOutputStream.PutNextEntry(entry);

		int count = fs.Read(buffer, 0, buffer.Length);
		while (count > 0) {
			zipOutputStream.Write(buffer, 0, count);
			count = fs.Read(buffer, 0, buffer.Length);
			if (!Response.IsClientConnected) {
				break;
			}
			Response.Flush();
		}
		fs.Close();
	}
	zipOutputStream.Close();

	Response.Flush();
	Response.End();
}

VB
' the aspx page has just one line e.g. <%@ Page language="vb" Codebehind=...
' but if you must run this from within a page that has other output, start with a Response.Clear()

Imports ICSharpCode.SharpZipLib.Zip

' This will accumulate each of the files named in the fileList into a zip file,
' and stream it to the browser.
' This approach writes directly to the Response OutputStream.
' The browser starts to receive data immediately which should avoid timeout problems.
' This also avoids an intermediate memorystream, saving memory on large files.
'
Private Sub DownloadZipToBrowser(zipFileList As List(Of String))

	Response.ContentType = "application/zip"
	' If the browser is receiving a mangled zipfile, IIS Compression may cause this problem. Some members have found that
	'    Response.ContentType = "application/octet-stream"     has solved this. May be specific to Internet Explorer.

	Response.AppendHeader("content-disposition", "attachment; filename=""Download.zip""")
	response.CacheControl = "Private"
	response.Cache.SetExpires(DateTime.Now.AddMinutes(3))
	' or put a timestamp in the filename in the content-disposition
	Dim buffer As Byte() = New Byte(4095) {}

	Dim zipOutputStream As New ZipOutputStream(Response.OutputStream)
	zipOutputStream.SetLevel(3)		'0-9, 9 being the highest level of compression
	For Each fileName As String In zipFileList

		Dim fs As Stream = File.OpenRead(fileName)
		' or any suitable inputstream
		Dim entry As New ZipEntry(ZipEntry.CleanName(fileName))
		entry.Size = fs.Length
		' Setting the Size provides WinXP built-in extractor compatibility,
		'  but if not available, you can set zipOutputStream.UseZip64 = UseZip64.Off instead.

		zipOutputStream.PutNextEntry(entry)

		Dim count As Integer = fs.Read(buffer, 0, buffer.Length)
		While count > 0
			zipOutputStream.Write(buffer, 0, count)
			count = fs.Read(buffer, 0, buffer.Length)
			If Not Response.IsClientConnected Then
				Exit While
			End If
			Response.Flush()
		End While
		fs.Close()
	Next
	zipOutputStream.Close()

	Response.Flush()
	Response.End()
End Sub

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 archiveFilenameIn, string password, string outFolder) {
	ZipFile zf = null;
	try {
		FileStream fs = File.OpenRead(archiveFilenameIn);
		zf = new ZipFile(fs);
		if (!String.IsNullOrEmpty(password)) {
			zf.Password = password;		// AES encrypted entries are handled automatically
		}
		foreach (ZipEntry zipEntry in zf) {
			if (!zipEntry.IsFile) {
				continue;			// Ignore directories
			}
			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.

			byte[] buffer = new byte[4096];		// 4K is optimum
			Stream zipStream = zf.GetInputStream(zipEntry);

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

			// 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(zipStream, streamWriter, buffer);
			}
		}
	} finally {
		if (zf != null) {
			zf.IsStreamOwner = true; // Makes close also shut the underlying stream
			zf.Close(); // Ensure we release resources
		}
	}
}

VB
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



Unpack a Zip - including embedded zips - and re-pack into a new zip or memorystream

This sample illustrates two major aspects:
  • how to extract files from embedded zips (a zip within a zip).
  • how to rebuild the contents into a new zip (optionally changing compression levels and changing encryption).

This example includes disk vs memorystream.

C#
using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;

private ZipOutputStream _zipOut;
private byte[] _buffer = new byte[4096];

// This example illustrates reading an input disk file (or any input stream),
// extracting the individual files, including from embedded zipfiles,
// and writing them to a new zipfile with an output memorystream or disk file.
//
public void DoRebuildFile(string zipFileIn, string password) {

	Stream inStream = File.OpenRead(zipFileIn);

	MemoryStream outputMemStream = new MemoryStream();
	_zipOut = new ZipOutputStream(outputMemStream);
	_zipOut.IsStreamOwner = false;	// False stops the Close also Closing the underlying stream.

	// To output to a disk file, replace the above with
	//
	//   FileStream fsOut = File.Create(newZipFileName);
	//   _zipOut = new ZipOutputStream(fsOut);
	//   _zipOut.IsStreamOwner = true;	// Makes the Close also Close the underlying stream.

	_zipOut.SetLevel(3);
	_zipOut.Password = password;		// optional

	RecursiveExtractRebuild(inStream);
	inStream.Close();

	// Must finish the ZipOutputStream to finalise output before using outputMemStream.
	_zipOut.Close();

	outputMemStream.Position = 0;

	// At this point the underlying output memory stream (outputMemStream) contains the zip.
	// If outputting to a web response, see the "Create a Zip as a browser download attachment in IIS" example above.
	// See the "Create a Zip to a memory stream or byte array" example for other output options.
}

// Calls itself recursively if embedded zip
//
private void RecursiveExtractRebuild(Stream str) {

	ZipFile zipFile = new ZipFile(str);
	zipFile.IsStreamOwner = false;
	
	foreach (ZipEntry zipEntry in zipFile) {
		if (!zipEntry.IsFile)
			continue;
		String entryFileName = zipEntry.Name; // or Path.GetFileName(zipEntry.Name) to omit folder
		// Specify any other filtering here.

		Stream zipStream = zipFile.GetInputStream(zipEntry);
		// Zips-within-zips are extracted. If you don't want this and wish to keep embedded zips as-is, just delete these 3 lines. 
		if (entryFileName.EndsWith(".zip", StringComparison.OrdinalIgnoreCase)) {
			RecursiveExtractRebuild(zipStream);
		} else {
			ZipEntry newEntry = new ZipEntry(entryFileName);
			newEntry.DateTime = zipEntry.DateTime;
			newEntry.Size = zipEntry.Size;
			// Setting the Size will allow the zip to be unpacked by XP's built-in extractor and other older code.

			_zipOut.PutNextEntry(newEntry);

			StreamUtils.Copy(zipStream, _zipOut, _buffer);
			_zipOut.CloseEntry();
		}
	}
}

VB
Imports ICSharpCode.SharpZipLib.Core
Imports ICSharpCode.SharpZipLib.Zip

Private _zipOut As ZipOutputStream
Private _buffer As Byte() = New Byte(4095) {}

' This example illustrates reading an input disk file (or any input stream),
' extracting the individual files, including from embedded zipfiles,
' and writing them to a new zipfile with an output memorystream or disk file.
'
Public Sub DoRebuildFile(zipFileIn As String, password As String)

	Dim inStream As Stream = File.OpenRead(zipFileIn)

	Dim outputMemStream As New MemoryStream()
	_zipOut = New ZipOutputStream(outputMemStream)
	_zipOut.IsStreamOwner = False	' False stops the Close also Closing the underlying stream.

	' To output to a disk file, replace the above with
	'
	'   FileStream fsOut = File.Create(newZipFileName);
	'   _zipOut = new ZipOutputStream(fsOut);
	'   _zipOut.IsStreamOwner = true;	' Makes the Close also Close the underlying stream.

	_zipOut.SetLevel(3)
	_zipOut.Password = password		' optional
	RecursiveExtractRebuild(inStream)
	inStream.Close()

	' Must finish the ZipOutputStream to finalise output before using outputMemStream.
	_zipOut.Close()

	outputMemStream.Position = 0

	' At this point the underlying output memory stream (outputMemStream) contains the zip.
	' If outputting to a web response, see the "Create a Zip as a browser download attachment in IIS" example above.
	' See the "Create a Zip to a memory stream or byte array" example for other output options.
End Sub

' Calls itself recursively if embedded zip
'
Private Sub RecursiveExtractRebuild(str As Stream)

	Dim zipFile As New ZipFile(str)
	zipFile.IsStreamOwner = False

	For Each zipEntry As ZipEntry In zipFile
		If Not zipEntry.IsFile Then
			Continue For
		End If
		Dim entryFileName As [String] = zipEntry.Name	' or Path.GetFileName(zipEntry.Name) to omit folder
		' Specify any other filtering here.

		Dim zipStream As Stream = zipFile.GetInputStream(zipEntry)
		' Zips-within-zips are extracted. If you don't want this and wish to keep embedded zips as-is, just delete these 3 lines. 
		If entryFileName.EndsWith(".zip", StringComparison.OrdinalIgnoreCase) Then
			RecursiveExtractRebuild(zipStream)
		Else
			Dim newEntry As New ZipEntry(entryFileName)
			newEntry.DateTime = zipEntry.DateTime
			newEntry.Size = zipEntry.Size
			' Setting the Size will allow the zip to be unpacked by XP's built-in extractor and other older code.

			_zipOut.PutNextEntry(newEntry)

			StreamUtils.Copy(zipStream, _zipOut, _buffer)
			_zipOut.CloseEntry()
		End If
	Next
End Sub



Unpack a zip using ZipInputStream (eg for Unseekable input streams)

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:
	WebClient webClient = new WebClient();
	Stream data = webClient.OpenRead("http://www.example.com/test.zip");
	// This stream cannot be opened with the ZipFile class because CanSeek is false.
	GetViaZipInput(data, @"c:\temp");

public void GetViaZipInput(Stream zipStream, string outFolder) {

	ZipInputStream zipInputStream = new ZipInputStream(zipStream);
	ZipEntry zipEntry = zipInputStream.GetNextEntry();
	while (zipEntry != null) {
		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.

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

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

		// 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);
		}
		zipEntry = zipInputStream.GetNextEntry();
	}
}

VB
' 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.
	GetViaZipInput(data, "c:\temp")

Public Sub GetViaZipInput(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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章