Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A Console ZIP Utility Using ICSharpCode SharpZipLib

0.00/5 (No votes)
30 Nov 2007 1  
A sample but usable program using the SharpZipLib.
Screenshot - MZip.gif

Abstract

I was seeking a program for backing up my files in a differential way: being able to store the files modified since last back-up. To do so, there is a good way: to use the last-modified date of the file. I wanted as well to record them in a widely spread format to have a good chance of being able to restore them within several years.

The zip format seems to be the best one for this purpose. And I wanted the process to be completely automatic in order to avoid losing time and potentially make mistakes while saving the files. To that end, a good old batch file seemed to be the best. So the problem was finding a zip command line utility able to do that.

Only one free program like this seems to exist on the internet: the open source Info-ZIP utility. But there is a code page issue with Info-Zip, which makes zip files produced by InfoZip completely readable by some zippers, but not all, when the file names contain extended characters like those used by some European languages. For example, the Windows built-in zip functionality displays wrong file names if these names contain extended characters and if the zip file was created with Info-Zip. It's not important if the file names contain only US standard characters, but if, for example, they contain specific European characters, such as ń, �, �, etc... it's not very convenient.

With no other utility being available, I decided to write one myself. Several zip libraries are available on the net. I decided to use the ic#code one. It worked relatively simply.
I made this program available for the CodeProject community as a complete sample program using this library. I hope that it could be helpful to readers wanting to add add a zip functionality to their software, or simply to use the utility for their own backup purpose.

Background

Several other CodeProject articles talk about the ic#code zip library, like this one which gives a basic view about the way to zip and unzip files.

Using the Utility

The utility can be used as a conventional zip utility, but it has a special feature to easily and automatically create a differential backup file. When started with the conventional /? parameter, it displays its help text :

MZip
Zip archive creating and updating utility.
Syntax:
MZip /zip=Zip file name [/a] [/d=date or file name] [/r|R] [/l] file(s) or
directory(ies) name(s)
/zip=Name of the file to create or update
/a if present and if the zip file exists, its contents is merged with
the new files otherwise, a new zip file is created.
/d=date/time The files are stored to the zip archive if they were modified
after this date/time.
A file name can be given instead of a date. In this case the date/time when
the file was last modified is used as a starting date for storing files.
If a date/time is given, its format depends on the language settings of
the computer and can be any usual format for a date/time such as 1/1/2000 8:00.
If a date such as 10:30 is given it means today at 10:30.
[/l] tells the program only to list the files, not to store them.
/r means to store the relative directory of the files when a directory name
is given, and the absolute path name when a file name is given.
/R means to store the absolute path of the files in any case.
This program is provided on an "AS-IS" basis. You can use it freely but
at your own risks. The author is not liable for any direct
or indirect damage caused by the program.

What is specific is the /d= optional parameter. This parameter can contain either a date/time string or a file name. If it contains a date, it means that the program must record files in the selection, modified after this date. If it contains a file name, it means that the program must take this date in the last-modified date of this file. This makes it possible to create a very simple batch file to create a differential bakup:

MZip /zip=DifferentialBackup.zip /d=MyTimeStamp.txt /R c:\MyDirectory
echo My time stamp >MyTimeStamp.txt

Such a batch file will create an archive containing the files modified since the last time it was started.

A slightly more complex and more interesting batch would be:

date /t >%temp%\MyDate.txt
set /p MyDate= <%temp%\MyDate.txt
set MyDate=%MyDate: =%
set MyDate=%MyDate:/=.%
if exist %temp%\MyDate.txt del %temp%\MyDate.txt
MZip /zip=Backup.%MyDate%.zip /d=MyTimeStamp.txt /R c:\MyDirectory
echo My time stamp >MyTimeStamp.txt

This batch file gives a name depending on the date to the backup file. You can, for example, burn the resulting file directly to a CD or a DVD to make an efficient backup, and do it each week: each weekly file will have a different name.

In case of disaster, the files can be recovered by unzipping them in chronological order.

Because MZip creates zip files compatible with the Windows zip feature, it's also a good choice when you need to zip files from the command line (mainly if your language uses an extended character set).

Using the Code

The major part of the code aims to make a list of the files to compress and to store it to a SortedList collection.

One thing is interesting here: the AnalyseCommande class, which is a reusable class parsing the command line in a relatively flexible way.

What is also interesting, is the use of the SharpZipLib library, either for reading or for writing a zip file. To read a file, you first have to create a FileStream object. Then, from this object to create a ZipInputSream object, and, to read a file within the archive, to create a ZipEntry object corresponding to the file you want to read. In this program they are selected sequentially one after each other. Then simply read the data like an ordinary stream, using the Read method of the ZipInputStream object. That's all and it's very simple and short as shown in the following part of the program:

FlotEntree=new FileStream(NomFichierZip,FileMode.Open,FileAccess.Read,
    FileShare.None);
FichierZipEntree=new ZipInputStream(FlotEntree);
//then we access all the entries of the existing archive

for(MonEntreeLue=FichierZipEntree.GetNextEntry();
    MonEntreeLue!=null;MonEntreeLue=FichierZipEntree.GetNextEntry())
{
    //here the entry has to be copied to the new archive, this is done by

    //creating a "ZipEntry" object, then to feed the zip flow with the

    //data of the file 

    //Creating the zip entry

    MonEntree=new ZipEntry(ZipEntry.CleanName(MonEntreeLue.Name));    
    //setting the necessary parameters from the original entry, here, the date

    MonEntree.DateTime=MonEntreeLue.DateTime;
    MonEntree.Size=MonEntreeLue.Size;            //... and the size

    //adding the new entry to the zip file

    FichierZipSortie.PutNextEntry(MonEntree);    
    for(LongueurRestante=(int)FichierZipEntree.Length;LongueurRestante!=0;)
    {
        //this loop copies the file contents from the original archive

        //to the new one by unzipping from the old one then zipping to

        //the new one

        LongueurLue=FichierZipEntree.Read(BufferTransfert,0,
            LongueurRestante<1024*1024?LongueurRestante:1024*1024);
        //unzipping a block

        //no byte read, we are at the end of the block

        if(LongueurLue==0)break;    
        //writing the block

        FichierZipSortie.Write(BufferTransfert,0,LongueurLue);    
        LongueurRestante-=LongueurLue;    //Computing the length to be read

    }
}

This program is slightly more complex than simply reading the file as it writes the read data to the new zip archive.

Writing to a zip file is as simple, but it uses the ZipOutpuStream class.

The complete program was created with the SharpDevelop IDE, an interesting open source IDE for .NET, and the sln project works with this IDE. It should work as well with Microsoft's tools. The MZip.exe program is autonomous and does not need any DLL to work. This was made possible by using the Microsoft's ILMerge utility to merge the original exe file (created by the compiler) and the DLL.

Points of Interest

Programming this tool was not very complex. But the SharpZipLib offers a lot of classes, which sometimes look like to be equivalent and it is not completely easy to find his way through all these classes. This program shows an efficient way to read ot create zip files through two main classes, ZipInputStream and ZipOutputStream.

My purpose was to help any developer wanting to create zip functionalities. Using this library the way it's done in my program is easy and quick and gives great results.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here