Introduction

This article shall describe an approach that may be used to collect files from multiple locations and zip them up into a single zipped folder. The code contained in the sample project may be useful, if one needs to gather up multiple files, zip them up, and then do something with them, such as upload the zipped files to a server location for storage or processing. The application uses the SharpZipLib for the basis of the compression function.

SharpZipLib-for-the-basis-of-the-compression-function.jpg

Figure 1: Demo User Interface for Folder Compression Project.

As was mentioned, the example code is dependent upon the SharpZipLib libraries; these libraries may be downloaded from this location:

http://www.icsharpcode.net/OpenSource/SharpZipLib/

In addition to handling zip files, the library also handles tar, gzip, and bzip2 compression.

The Solution

The solution contains a single project. The example is provided in the form of a single Windows Forms project; the project contains a single main form (frmMain); the references are all in the default configuration, with the exception being that the SharpZipLib DLL has been added. Having downloaded the DLL from thewww.icsharpcode.net web, the download was installed into the local file system and was adding by using the "Add Reference" dialog's Browse option. All of the code necessary to drive the application is included in the main form's code file.

Add-Reference-dialog-Browse-option.jpg

Figure 2:The Solution Explorer Showing the Project.

The Code: Compress Folders - Main Form

The Compress Folders project is a Windows Forms project containing a single form. All UI and code required by the project are contained in the single main form (frmMain.vb).

The only references added to the project were those necessary to support the use of the SharpZipLib in the project, System.IO, and System.Text. The imports and class declaration are as follows:

Imports ICSharpCode.SharpZipLib.Checksums

Imports ICSharpCode.SharpZipLib.Zip

Imports ICSharpCode.SharpZipLib.GZip

Imports System.IO

Imports System.Text

Public Class frmMain

The next block of code is used to handle the browse button's click event. This button is used to display the open file dialog; this dialog is used to capture the path to a folder that the user wants to include in the zipped folder. The code is annotated such that you may review descriptions of what each section of the code is doing by reading though this code block:

Private Sub btnBrowse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) HandlesbtnBrowse.Click

' configure the open file dialog

openFileDialog1.Title = "Add File"

openFileDialog1.Filter = "All Files (*.*)|*.*"

openFileDialog1.FileName = ""

' return if the user cancels the operation

If openFileDialog1.ShowDialog() = DialogResult.Cancel Then

Return

End If

' set a local variable to contain the file name

' captured from the open file dialog

Dim sFilePath As String

sFilePath = openFileDialog1.FileName

If sFilePath = "" Then

Return

End If

' make sure the file exists before adding

' its path to the list of files to be

' compressed

If System.IO.File.Exists(sFilePath) = False Then

Return

Else

txtAddFile.Text = sFilePath

End If

End Sub

The next block of code is used to add a file selected by the previous method (Browse button) and add to a list of files to included in the zipped folder. Again, this section of code is annotated to describe what each part of the code does.

Private Sub btnAddFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) HandlesbtnAddFile.Click

' Check for content in the text box

If txtAddFile.Text = String.Empty Then

MessageBox.Show("Use the browse button to search for " & _

"the file to be added.", "Missing File Name")

Return

End If

' Only allow the file to be added if the file is not a duplicate

Dim i As Integer

For i = 0 To lstFilePaths.Items.Count - 1

If lstFilePaths.Items(i).ToString() =

txtAddFile.Text.ToString() Then

MessageBox.Show("That file has already been added to the list.", "Duplicate")

Return

End If

Next

' Add the file to the listbox list

If txtAddFile.Text <> String.Empty Then

lstFilePaths.Items.Add(txtAddFile.Text.ToString())

End If

' clear the textbox and move the focus back to the textbox

txtAddFile.Text = String.Empty

txtAddFile.Focus()

End Sub

The next section of code is the Remove button's click event handler; this method allows the user to remove items from the listbox list after they have been added using the browse button and add button.

Private Sub btnRemoveFile_Click(ByVal sender As System.Object, ByVal e As

System.EventArgs) Handles btnRemoveFile.Click

' remove the selected item from the listbox

Try

lstFilePaths.Items.Remove(lstFilePaths.SelectedItem)

Catch ex As Exception

MessageBox.Show(ex.Message, "Error")

End Try

End Sub

Next up is a button event handler that uses the Folder Browser Dialog control to help the user to specify a destination path for the finished zip file.

Private Sub btnSaveBrowse_Click(ByVal sender As System.Object, ByVal e As

System.EventArgs) Handles btnSaveBrowse.Click

' clear the folder path

txtSaveTo.Text = String.Empty

' Show the FolderBrowserDialog.

' use the selected path to set the save to location

Dim result As DialogResult

result = folderBrowserDialog1.ShowDialog()

If result = DialogResult.OK Then

txtSaveTo.Text = folderBrowserDialog1.SelectedPath

End If

End Sub

The next button click event handler contains the code used to gather up the marked files and zip them up to the destination folder set. The code will gather up the identified files, copy the files to a temporary folder inside the destination folder, zip them up, and then remove the temporary folder. This code is also annotated and you may review the notes that are contained within the code block, to read a description of what is happening at each stage in the progress.

Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click

' make sure there are files to zip

If lstFilePaths.Items.Count < 1 Then

MessageBox.Show("There are no files queued for the zip operation", "Empty File Set")

Return

End If

' make sure there is a destination defined

If txtSaveTo.Text = String.Empty Then

MessageBox.Show("No destination file has been defined.", "Save To Empty")

Return

End If

' display the message showing zip in progress

lblUpdate.Visible = True

lblUpdate.Refresh()

' name the zip file whatever the folder is named

' by splitting the file path to get the folder name

Dim sTemp As String() = txtSaveTo.Text.Split("\")

Dim sZipFileName As String = sTemp(sTemp.Length - 1).ToString()

' check to see if zipped file already exists

' user may rename it in the text box if it does.

Dim fi As FileInfo =

New FileInfo(txtSaveTo.Text + "\" + sZipFileName + ".zip")

If fi.Exists Then

' tell the user if the file already exists

Try

Dim sb As StringBuilder = New StringBuilder()

sb.Append("The file " + sZipFileName + " already exists. ")

sb.Append("You may rename it in the save to text box.")

MessageBox.Show(sb.ToString(), "Existing File Name")

txtSaveTo.Text = String.Empty

txtSaveTo.Focus()

Return

Catch ex As Exception

MessageBox.Show(ex.Message, "File Error")

Return

End Try

End If

fi = Nothing

' Check for the existence of the target folder and

' create it if it does not exist

If (Not System.IO.Directory.Exists(txtSaveTo.Text + "\TempZipFile\")) Then

Then

System.IO.Directory.CreateDirectory(txtSaveTo.Text +

"\TempZipFile\")

End If

' Set up a string to hold the path to the temp folder

Dim sTargetFolderPath As String = (txtSaveTo.Text + "\TempZipFile\")

' Process the files and move each into the target folder

Dim i As Integer

For i = 0 To lstFilePaths.Items.Count - 1

Dim filePath As String = lstFilePaths.Items(i).ToString()

Dim fi2 As FileInfo = New FileInfo(filePath)

If fi2.Exists Then

' move it to the folder

Try

fi2.CopyTo(sTargetFolderPath + fi2.Name, True)

Catch

' clean up if the operation failed

System.IO.Directory.Delete(sTargetFolderPath)

MessageBox.Show("Could not copy files to temp folder.", "File Error")

Return

End Try

End If

fi2 = Nothing

Next

' zip up the files

Try

lblUpdate.Visible = True

lblUpdate.Refresh()

Dim filenames As String() = Directory.GetFiles(sTargetFolderPath)

' Zip up the files - From SharpZipLib Demo Code

Dim s As ZipOutputStream = New

ZipOutputStream(File.Create(txtSaveTo.Text +

"\" + sZipFileName + ".zip"))

s.SetLevel(9) ' 0-9, 9 being the highest level of compression

Dim buffer() As Byte

ReDim buffer(4096)

Dim f As String

For Each f In filenames

Dim entry As ZipEntry = New ZipEntry(Path.GetFileName(f))

entry.DateTime = DateTime.Now

s.PutNextEntry(entry)

Dim fs As FileStream = File.OpenRead(f)

Dim sourceBytes As Integer = 1

Do Until (sourceBytes <= 0)

sourceBytes = fs.Read(buffer, 0, buffer.Length)

s.Write(buffer, 0, sourceBytes)

Loop

fs.Close()

Next

' clean up

s.Finish()

s.Close()

' remove the progress note

lblUpdate.Visible = False

' Notify user

MessageBox.Show("Zip file " + txtSaveTo.Text + " created.")

' empty everything

lstFilePaths.Items.Clear()

txtSaveTo.Text = String.Empty

txtAddFile.Text = String.Empty

' clean up files by deleting the temp folder and its content

System.IO.Directory.Delete(sTargetFolderPath, True)

Catch ex As Exception

MessageBox.Show(ex.Message.ToString(), "Zip Operation Error")

End Try

End Sub

The remaining code in the project is that used to terminate the application.

Private Sub btnExit_Click(ByVal sender As System.Object, ByVal e As

System.EventArgs) Handles btnExit.Click

Application.Exit()

End Sub

That here wraps up the description of the code used in this project.

Summary

This example demonstrates zipping up a folder using the SharpZipLib; in this example, the interface is provided in the form of a stand alone desktop application. The same approach described in this project could be applied within the context of a large application, that may be required to gather up multiple files and zip them into a single zipped folder. As with all things, there are other ways to do this same sort of thing, however, given the availability of the SharpZipLib, this is a relatively simple process.