Please navigate to the bottom of the page for Table of Contents

Tuesday, May 31, 2011

Explain System.IO and System.IO.Compression namespaces with an example

A through understanding of the System.IO namespace is very important when you are developing applications that deal with the file system. In addition, if the files that you are dealing with are large in size, you should probably be very comfortable in System.IO and System.IO.Compression namespaces. A good deal of interview questions come from this area.

Let’s tackle relatively simple problem: Write a simple function that compresses a source file and writes it out a compressed zip archive and vice-versa. The solution is simple: We can create 2 streams: one to read the file and the second to write to a file. Then depending on whether we are compressing or decompressing, we can use a GZipStream class to wrap the read or write streams. The complete program below shows a function that allows you to compress/decompress a file.

using System;
using System.IO;
using System.IO.Compression;

namespace ConsoleApplication1
{
class FileExamples
{
public static void Compress(string inFile, string outFile, bool compress)
{
// error checking
if (!File.Exists(inFile))
throw new ArgumentException("inFile does not exist");
if (File.Exists(outFile))
throw new ArgumentException("outFile exists");

// now with pleasantaries out, let's create our streams
// input stream
using (Stream inStream = File.Open(
inFile, // the file to open
FileMode.Open, // try to open an existing file
FileAccess.Read, // read only access
FileShare.None)) // lock the file till we are done
{
// output stream
using (Stream outStream = File.Open(
outFile, // the file to write to
FileMode.Create, // create.overwrite
FileAccess.Write, // write access please
FileShare.None)) // lock it till we are done
{
// now that we have opened both in/out streams
// let's wrap either one of them based on
// compression or decompression
using (GZipStream gzipStream = new GZipStream(
// select the correct stream and compression type
compress ? outStream : inStream,
compress ? CompressionMode.Compress :
CompressionMode.Decompress))
{
// now we have wrapped the correct stream
// for reading; do the same for writing
Stream readFrom = compress ? inStream : gzipStream;
Stream writeTo = compress ? gzipStream : outStream;

// since we are reading using base Stream class
// we will have to read using byte array
// we could have also wrapped this is a higher
// stream (Buffered, etc, but that would
// complicate this example further

// we will use a buffer size of 16384
// as that maximizes the performance
byte[] buffer = new byte[16384];
int byteCount = 0;

// move data from in to out
do
{
// read
byteCount = readFrom.Read(buffer, 0, 16384);
// write
writeTo.Write(buffer, 0, byteCount);
} while (byteCount > 0);
}
}
}
}
}
}


There are some obvious improvements that you can do to this program to make it more efficient. I would like you to propose some changes to make this more robust. Please do refer to the MSDN documentation on the System.IO namespace and File and Stream IO section to read in more details about this powerful library.

6 comments: