Pages

Advertisement

Wednesday, July 11, 2007

Compressing/Decompressing Your Files

One of the many new libraries included with .NET 2.0 allows for compression and decompression of files using the gzip file format. The major downside to this format is that it isn't compatible with the built-in Compressed Folders format built into Windows XP. However, I was able to open a compressed file with WinZip after I renamed the file with a ".Z" extension. WinZip still needed the original filename that I compressed, but once I provided that, it was able to decompress the file.

That said, this is still a helpful library when you need to simply save some space and don't need to use the compressed files with any other applications. The following snippet of code shows how to compress a file. You can do a variety of things with the various Stream objects in System.IO, but this particular version seems to work fine:

FileStream fs = new FileStream("es_resume.doc", FileMode.Open);
byte[] input = new byte[fs.Length];
fs.Read(input, 0, input.Length);
fs.Close();

FileStream fsOutput = new FileStream("es_resume.gzip",
FileMode.Create,
FileAccess.Write);
GZipStream zip = new GZipStream(fsOutput, CompressionMode.Compress);

zip.Write(input, 0, input.Length);
zip.Close();
fsOutput.Close();

This snippet also needs to have System.IO and System.IO.Compression added as using statements at the top of the file. The basic process is to read the input file into a buffer first. You then set up an output file stream to use with the GZipStream object. Finally, you use the strea, to write the buffer; the buffer then compresses it and writes it to the output file. Closing the files is important, so I recommend putting the Close methods in a finally block wrapped around any code you use involving files. That will prevent the files from being "locked up" by the system.

Decompressing the file is basically the reverse of the compression process, but I had to use a different version of the code to do it:

FileStream fs = new FileStream("es_resume.gzip", FileMode.Open);
FileStream fsOutput = new FileStream("es_resume2.doc",
FileMode.Create,
FileAccess.Write);
GZipStream zip = new GZipStream(fs, CompressionMode.Decompress, true);

byte[] buffer = new byte[4096];
int bytesRead;
bool continueLoop = true;
while (continueLoop)
{
bytesRead = zip.Read(buffer, 0, buffer.Length);
if (bytesRead == 0)
break;
fsOutput.Write(buffer, 0, bytesRead);
}
zip.Close();
fsOutput.Close();
fs.Close();

In this case, I read a chunk of data from the file, decompressed it, and wrote it to the output file. I had to do it this way because the Length property of the zip GZipStream object is never a valid value, apparently by design. However, this block of code does work: it decompresses the compressed file back to its original size. It really doesn't matter what extension you put on the compressed file, but you do need to remember what filename was used originally.

If you need a true ZIP format that is compatible with the Compressed Folders/WinZip tools, several versions are available as open source, including SharpZipLib.

No comments:

Post a Comment