Geekpedia Programming Tutorials






Zipping files using GZipStream

In this tutorial we're going to use the new namespace of .NET 2.0, System.IO.Compression, which will give us access to the GZipStream class which will then allow us to compress and decompress ZIP files.

On Friday, June 16th 2006 at 09:42 AM
By Andrew Pociu (View Profile)
*****   (Rated 4.2 with 14 votes)
Contextual Ads
More C# Resources
Advertisement
Download this Visual Studio 2005 project Download this project (Visual Studio 2005)

The GZipStream class

Before .NET Framework 2.0 if you wanted to compress files you had to use a 3rd party library capable of doing that. In the new version there is a new namespace: System.IO.Compression that contains the GZipStream class. The GZipStream class has methods allowing us to both compress and decompress a file into a zip archive.

The disadvantage of using the GZipStream class over a 3rd party product is that it has limited capabilities. One of the limitations is that you cannot give a name to the file that you place in the archive. When GZipStream compresses the file into a ZIP archive, it takes the sequence of bytes from that file and uses compression algorithms that create a smaller sequence of bytes. The new sequence of bytes is put into the new ZIP file. When you open the ZIP file you will open the archived file itself; most popular ZIP extractors (WinZip, WinRar, etc.) will show you the content of the ZIP as a file that has the same as the archive itself:

WinRar

This is because the GZipStream class does not specify a file name in the headers, as metadata, since in the specifications of the GZIP file format, declaring a name is optional. This may not bother you if you are using this class to compress files used by your application (such as archiving old documents) and when the usage of the GZipStream class comes just a single piece of the puzzle in a larger application.
On the other hand, if you're looking to build an application that has the solely purpose of zipping and unzipping files, you will encounter some of GZipStream's limitations. If you decide to use a 3rd party class library in that case, or if you prefer to stick to GZipStream, is your choice. There is a workaround for giving file names to the ZIPs content by modifying the headers yourself. For information on how to change the headers, please see the MSDN Magazine article entitled NamedGZipStream, Covariance and Contravariance.

Zipping (sample application)

Let's start by creating a new Windows application project into Visual Studio 2005. Add to the form a TextBox and two Buttons. The TextBox is entitled txtPath and it will hold the path to the file to compress. The Buttons are entitled btnBrowse and btnCompress. The first one will show an OpenFileDialog for picking a file to compress, and the second one - btnCompress - will show a SaveFileDialog followed by the actual compressing and saving process. Speaking of these two dialogs, make sure you add them to our application and name them openFile and saveFile.

The two important namespaces we'll use need to be added at the top of the class file so we don't have to write really long lines:


using System.IO;

using System.IO.Compression;


Now double click btnBrowse and its Click event will be created. Inside it use the following code that displays the OpenFileDialog and allows the user to pick a file:


// Show the dialog where the user chooses the file to compress

if (openFile.ShowDialog() == DialogResult.OK)

{

txtPath.Text = openFile.FileName;

}


Now that we got the path, it's time to take that file and compress it. This happens when the user clicks on the btnCompress button, thus double-click it to get to its Click event and inside use the following code:


// If the user has selected a path where to put the compressed file

if (saveFile.ShowDialog() == DialogResult.OK)

{

// Bytes array in which we're going to store the actual file to be compressed

byte[] bufferWrite;

// Will open the file to be compressed

FileStream fsSource;

// Will write the new zip file

FileStream fsDest;

GZipStream gzCompressed;

fsSource = new FileStream(txtPath.Text, FileMode.Open, FileAccess.Read, FileShare.Read);

// Set the buffer size to the size of the file

bufferWrite = new byte[fsSource.Length];

// Read the data from the stream into the buffer

fsSource.Read(bufferWrite, 0, bufferWrite.Length);

// Open the FileStream to write to

fsDest = new FileStream(saveFile.FileName, FileMode.OpenOrCreate, FileAccess.Write);

// Will hold the compressed stream created from the destination stream

gzCompressed = new GZipStream(fsDest, CompressionMode.Compress, true);

// Write the compressed stream from the bytes array to a file

gzCompressed.Write(bufferWrite, 0, bufferWrite.Length);

// Close the streams

fsSource.Close();

gzCompressed.Close();

fsDest.Close();

}


Hopefully the comments will explain the code to you entirely; as you can see we don't have any room for error in this code for obvious reasons (keeping it simple and easy to comprehend), therefore in a production version you will probably want to catch exceptions and validate the user's input.

Your application should now look such as the one attached to this tutorial:

Zipping

Now that you know the basics of compressing files using .NET Framework 2.0, let's see how you can decompress files in the next tutorial: Unzipping compressed files using GZipStream.
Digg Digg It!     Del.icio.us Del.icio.us     Reddit Reddit     StumbleUpon StumbleIt     Newsvine Newsvine     Furl Furl     BlinkList BlinkList

Rate Rate this tutorial
Comment Current Comments
by sobia on Thursday, July 6th 2006 at 08:10 AM

I WANT TO COMPRESS AND DECOMPRESS IMAGE IN
c#

by Pedro on Friday, July 7th 2006 at 08:30 PM

Hi Andrei...

Great stuff here! Gratz...

Any idea why the compressed file after de-compressing comes with no extension?

by Andrei Pociu on Saturday, July 8th 2006 at 03:06 AM

Hello Pedro,

For the same reason it doesn't come with a file name (in WinRAR and similar tools it shows the name of the archive as being the name of the file so that you can extract it). The GZipStream class does not specify a file name in the headers, and the extension is part of the file name.

by Pedro on Saturday, July 8th 2006 at 08:10 AM

Ok!

Thanks Andrei!

P.S.- Great stuff mate! :p

by Ananth on Friday, July 28th 2006 at 06:55 AM

Hi, Nice work.
I was searching for this for a long time.
Thank you.

I have one more doubt. Its is possible to zip more than one file?

by This code does not w on Thursday, August 3rd 2006 at 08:30 AM

This code does not work when trying to unzip a .RAR file. it tells me that that Magic Number in header is wrong.. any way to correct this...?

by Mac on Monday, August 28th 2006 at 03:38 PM

Thanks for your code. When I run your code, I get the error, \"The Compressed (zipped) Folder is invalid or corrupted\". Winzip or moving files to a Zip Folder in XP works fine. Have you ever encounter an error like this? Thx.

by Muhammad Ahsan Shaki on Monday, November 20th 2006 at 12:00 AM

Great work..... my 138 file is compressing now i want to decompress my compressed file. how can i do.
i applied same code and change the mode but its not working and giving stream exception.... how can i decompress my compressed file using above code....

by wale on Friday, November 24th 2006 at 12:02 AM

I am getting really frustrated with this compression class. the output file won't open with winzip or any other utility for that matter... I am getting the same error as mac. does anyone know if i can programmatically call xp's built in compression utility? I don't c why not.

by kadualon on Sunday, December 10th 2006 at 02:27 PM

you should try opening with winrar then it will work.
WinZip requires some headers to be written which are not.

by Akshay on Thursday, January 4th 2007 at 05:12 AM

Hi Andrei. Great work. I have a doubt though. How can folders be compressed using this technique? Please point me in the right direction.

Thanks,
Akshay

by Arun T T on Monday, January 8th 2007 at 12:33 AM

hi

i am not satisfied with this code not because of any error in this code but i am in search of code that compresses more than 1 file into a single zip folder if anyone can help me please be kind on me

Arun

by sefa on Monday, February 12th 2007 at 04:57 PM

slm beyler nasılsınız ben geniusmaniac
how are you.
i am fine.
bye

by Divakar on Friday, April 20th 2007 at 04:02 AM

hi guys,
Thanks for your code. When I run your code, I get the error, "The Compressed (zipped) Folder is invalid or corrupted".
On that zipped folder,no files are there.How to solve?

Regards
Divakar

by Nilam on Monday, June 4th 2007 at 12:45 AM

Hi,
Actuallyi tried the same code. But while opening a compress file, it gives error like can not open file:This is not a valid archive.
So will u plz tell me why this happen?

by Michael Tomlinson on Monday, July 16th 2007 at 07:29 PM

See this MS blog for wrapper classes to to proper .zip files from multiple source files using .NET;
http://blogs.msdn.com/dotnetinterop/archive/2006/04/05/567402.aspx

by Jacob Kennedy on Tuesday, July 24th 2007 at 01:42 PM

I've got a workaround for getting the file extension into the archive. Rather than changing the extension of the archive itself I just tacked it onto the end (blah.txt.gz). When I open the archive, abracadabra, the file extension inside of the archive is correct.

Some people will say it's slightly sloppy but it works for all of the apps I work with (father-in-law says "works for the girls I go with").

Jake

by Tobias on Tuesday, July 24th 2007 at 05:03 PM

Thanks Jake, it works!

by Kristian on Thursday, July 26th 2007 at 01:44 AM

Those of you looking for a method of creating a real zip, should check out http://www.codeproject.com/csharp/compresswithwinshellapics.asp

by Chris on Wednesday, August 8th 2007 at 11:22 AM

The key to getting this to work is as Jacob pointed out. Your output file has to be named SomeName.txt.gz. If it has a Zip extension then you get the errors that others pointed out. If you don\'t include the original extension, then you get prompted to provide the extension (using WinZip).

by Sandeepan on Monday, March 24th 2008 at 08:33 AM

Hi...
quite impressive code..
i agree that winzip needs some header.... its working with winrar also..
but can u please tell me why windows XP's default extracter is not working???

by Pravara on Wednesday, March 26th 2008 at 02:05 AM

Can we use this method to compress an encrypted string to a specific number of characters?

by Lawrence on Sunday, April 20th 2008 at 05:22 PM

This seems to work if you add .rar to the end of the file name, then using WinRAR to decompress it. Windows unzip on Vista seems incredibly slow on most files, and doesn\'t work at all on Microsofts own .NET zip compression! I will just have to include a copy of WinRAR with my software.

by jayadev on Thursday, August 28th 2008 at 06:57 AM

it works fine a single file .but how to apply for entire can any one help me

by Cheeso on Thursday, March 5th 2009 at 03:19 AM

GZipStream does NOT DO ZIP FILES.
This is CONFUSING. GZipStream produces GZIP files, commonly with the .gz extension. WinRar can read .gz files, but they are NOT ZIP FILES.

To do Zip files you need a third-party library like DotNetZip. You cannot manipulate ZIP files with GZipStream.

by Naveen Sharma on Thursday, November 12th 2009 at 01:57 PM

hey great work man.....the code is impressive and working well....gr8...

by Thaya on Friday, December 4th 2009 at 08:09 AM

when i tried the above code . it works fine . after i tried to open / extract the file i am getting the below mentioned Error.
"cannot open a file : it does not appear valid archiev"

here is my code

string source = "D:/WorksapaceSamples/ CA.xls";
string Destination="D:/WorksapaceSamples/New Folder/ CA.zip";
FileStream fsource;
FileStream fdest;
byte[] bufferwrite;
GZipStream gzip;
fsource=new FileStream(source,FileMode.Open,FileAccess.Read,FileShare.Read);
bufferwrite = new byte[fsource.Length ];
fsource.Read(bufferwrite, 0, bufferwrite.Length);
fdest = new FileStream(Destination, FileMode.OpenOrCreate, FileAccess.Write);
gzip = new GZipStream(fdest, CompressionMode.Compress, true);
gzip.Write(bufferwrite, 0, bufferwrite.Length);
fsource.Close();
gzip.Close();
fdest.Close();
MessageBox.Show("OK");

-------------------------------------------------
its very urgent for me... if any body have fulle code please send to my mail.
thanks
thaya

by thaya on Friday, December 4th 2009 at 08:12 AM

thayananth_vel@yahoo.co.in
please reply this mail mail id.....

by Kiranteja on Wednesday, June 30th 2010 at 06:31 AM

sorry sir after i converted the 14.5KB file into zip the resultfile size is 20.KB..how to solve it reply me...!

by Mario on Tuesday, July 6th 2010 at 05:53 AM

Thanks, was looking exactly for this!


Comment Comment on this tutorial
Name: Email:
Message:
Comment Related Tutorials
There are no related tutorials.

Comment Related Source Code
There is no related source code.

Jobs C# Job Search
My skills include:
Enter a City:

Select a State:


Advanced Search >>
Advertisement

Free Magazine Subscriptions

Today's Pictures

Today's Video

Other Resources

Latest Download

Latest Icons