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.
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:
private long totalFileSize = 0L;
private long totalNumberFilesSelected = 0L;
private int partitionSize;
private int partitionSizeInBytes = 100000000;
private int compressionLevel = 9;
private String saveFileBase = "";
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:
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.
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.
Figure 3 – ZipMaker Main Window
Figure 4 – List of selected files appear in the list box
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
- A .NET Progress Dialog, Mathew Adams
- NLog
- #zipLib (SharpZipLib)