Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / WinForms

Automating Multipart Zip File Creation

4.67/5 (7 votes)
21 Apr 2008CPOL5 min read 1   1.6K  
Automatically creating multipart Zip files.

Introduction

Most guest accounts on file sharing sites have a 100 – 300 MB limit on the file sizes that can be uploaded. I usually use the WinZip splitting option to compress my files to be uploaded. At times, there can be problems uploading to the file sharing site. If the files you have uploaded were created using the split option, this means that the downloader would require all the parts to be downloaded before he/she can unzip the file. I wanted my shared image files to be available for viewing as soon as they were downloaded, without requiring all the parts of the archive to become available. I also did not want to manually guess the total file size limits when creating and adding to the zip archive. Due to these reasons, I decided to write a utility that could automatically create a multipart zip archive based on a user selectable pre-defined partition (100MB, 500MB, 1000MB) or a user-definable partition size. The user selects the file(s) to be archived, and based on the defined partition sizes, automatically creates a multipart zip archive for you.

System Overview

The utility was written in C#. To create the zip archive, I used the SharpZipLib [3] library. This is an open source Zip, GZip, Tar, and BZip2 compression library written in C#. For logging and debugging purposes, I used the NLog [2] library. The use cases for this utility are shown in Figure 1. ZipMaker allows a user to multiply or singly select the file(s) or file he/she wishes to archive. The destination directory and resultant archive name to be saved to can also be specified. If these are not specified, the system will automatically generate a filename based on the UUID and save the file(s) in the directory from which this application is run. In addition, the user can select the compression level (1 – 9); 9 being the best. The file partition size can also be user specified. So, for example, if you have selected 100 files to be archived and their total size came to 350MB and the partition size selected was 100MB, then four zip files will be created, each of these zip archives will be 100MB or less. If both these parameters are not specified, then the default compression level (9) and partition file size (100 MB) will be used.

Fig1.jpg

Figure 1 – Use Case diagram for ZipMaker

Design

The ZipMaker is made up of four modules. The class diagram in Figure 2 shows the components that make up this utility and their relationships. The main UI form is the ZipMakerForm; this handles all user interactions. In addition, I also make use of [1], which shows a progress dialog when performing the zipping operations. The ZipMakerForm class has several attributes. These are shown below:

C#
private long totalFileSize = 0L; /* In bytes */
private long totalNumberFilesSelected = 0L; /* Total number of files selected */
private int partitionSize; /* In MegaBytes */
private int partitionSizeInBytes = 100000000; /* defaulted to 100 MB */
private int compressionLevel = 9; /* defaults to 9 (best) */
private String saveFileBase = ""; /* Zip file to save as */
private ArrayList fileInfoList;
private ArrayList fileIndices = new ArrayList();
  • totalFileSize keeps a running total of the files to be archived;
  • totalNumberFilesSelected stores the total number of files selected by the user to be archived;
  • partitionSize captures the user specified file archive partition size in megabytes;
  • partitionSizeInBytes is the conversion factor from megabytes to bytes;
  • compressionLevel is an integer from 1 – 9, which is used to set the zip compression level;
  • saveFileBase is used to specify the root filename of the archive to be saved;
  • If there is only one archive, then the archive name will take on the value in saveFileBase; otherwise depending on the number of archives computed, the base name will have a number appended to it, up to the total number of archives computed. So, using the previous example of a user having selected 100 files to be archived with a total file size of 350MB and the partition size selected was 100MB, four zip files will be created, each of these zip archives will be 100MB or less. If the value of the attribute saveFileBase is testZipMaker, then each of the four zip archives will be named as follows: testZipMaker_1.zip, testZipMaker_2.zip, testZipMaker_3.zip, and testZipMaker_4.zip.

  • fileInfoList is used for storing the user selected file(s) attributes into an array list.
  • Each item of the array list stores a FileInfoItem object which contains the name of the file, its size, and directory location. Finally,

  • fileIndices is an array list that references the end points of a multipart archive.
  • In the four zip archive examples described above, the first zip archive stores the end point, 30, the second, 50, the third, 80, and the last, 100. We use the values from the fileIndices array list to reference back into the fileInfoList array to perform the actual zipping operations.

The main methods in this class are:

C#
private int computeNumberOfArchives()
private void createZipArchive()
private void doZip()

The method createZipArchive() is called when the user clicks the “Zip” button (afterall, the parameters have been set). createZipArchive(), in turn, calls doZip() which does the actual zipping operation using the APIs from [3]. Since I also want to provide some form of user feedback whilst the zipping operation is in progress, the progress bar call backs (Begin, StepTo, and End) are also embedded within these two methods. I modified this from [1] in order to integrate this component into my application. The computeNumberOfArchives() method computes the number of zip archives that needs to be created.

Fig2.jpg

Figure 2 – Class Diagram of ZipMaker

User Interface Flow

When the ZipMaker application is started, the following form is presented to the user. Pressing the Browse button brings up the File Open dialog, allowing the user to select the files he/she wishes to archive. After the files to be archived have been selected, these are shown in the list box (circled in red, Figure 4). The user can also change the default settings (file partition sizes and compression level). When he/she is satisfied with the parameters, he/she then clicks on the “Save As” button to specify the destination directory and archive filename to be saved. Clicking on the “Zip” button activates the zip operation. The progress bar in Figure 5 provides some form of user feedback whilst the archiving operation is being carried out.

Fig3.jpg

Figure 3 – ZipMaker Main Window

Fig4.jpg

Figure 4 – List of selected files appear in the list box

Fig5.jpg

Figure 5 – Progressbar

Conclusion

I have presented a simple utility to create a single or multipart zip archive based on user specifiable or pre-selected partition sizes. I hope you find this utility useful.

References

  1. A .NET Progress Dialog, Mathew Adams
  2. NLog
  3. #zipLib (SharpZipLib)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)