Compressing and Decompressing Files With C#

Introduction

To reduce the time needed for files to be transmitted over a network, Compression and Decompression techniques are very useful. Developers prefer to write code to compress files before sending them out to the network for a file upload process. Web applications get the most benefit out of it. The .NET Framework provides the System.IO.Compression namespace, which contains the compressing and decompressing libraries and streams. Developers can use these types to read and modify the contents of a compressed file.

Compression and Decompression Example

To create a Sample Compression and Decompression application in .NET, Open Visual Studio 2015 -> File Menu -> New, then Project. It will open a new project window. Choose the Console Application type. Specify the project name “PrjCompressDecompress” and click OK (see Figure 1).

.NET new console application
Figure 1: .NET new console application

Next, from the NuGet Package Manager, I have installed the System.IO.Compression library. You can see this in Figure 2.

Added System.IO.Compression library
Figure 2: Added System.IO.Compression library

After that, I have written the following CompressFiles function in the Program.cs file; it uses the System.IO.Compression namespace to compress the file to a .RAR extension. Refer to the following code snippet.

public static void CompressFiles(string strFIlePath)
{
   // Variables
   DateTime todaysdate;
   string dstFilenamewithpath = "";
   FileStream fsInFile = null;
   FileStream fsOutFile = null;
   GZipStream Myrar = null;
   byte[] filebuffer;
   int count = 0;

   try
   {
      todaysdate = DateTime.Now;
      dstFilenamewithpath = AppDomain.CurrentDomain.BaseDirectory
         + "\\" + "Request" + todaysdate.Day.ToString()
         + todaysdate.Month.ToString() + todaysdate.Year.ToString()
         + todaysdate.Hour.ToString()
         + todaysdate.Minute.ToString()
         + todaysdate.Second.ToString() + ".rar";

      fsOutFile = new FileStream(dstFilenamewithpath,
         FileMode.Create, FileAccess.Write, FileShare.None);
      Myrar = new GZipStream(fsOutFile,
         CompressionMode.Compress, true);
      fsInFile = new FileStream(strFIlePath, FileMode.Open,
         FileAccess.Read, FileShare.Read);
      filebuffer = new byte[fsInFile.Length];
      count = fsInFile.Read(filebuffer, 0, filebuffer.Length);
      fsInFile.Close();
      fsInFile = null;
      Myrar.Write(filebuffer, 0, filebuffer.Length);
   }

   catch (Exception ex)
   {
      System.Diagnostics.Debug.Assert(false, ex.ToString());
   }
   // Releasing objects
   finally
   {
      if (Myrar != null)
      {
         Myrar.Close();
         Myrar = null;
      }
      if (fsOutFile != null)
      {
         fsOutFile.Close();
        fsOutFile = null;
      }
      if (fsInFile != null)
      {
         fsInFile.Close();
         fsInFile = null;
      }
   }
}

Now, to decompress the .RAR file created in the preceding step, the following function is written.

public static void DecompressFiles(string strFIlePath)
{
   DateTime current;
   string dstFile = "";

   FileStream fsInFile = null;
   FileStream fsOutFile = null;
   GZipStream Myrar = null;
   const int bufferSize = 4096;
   byte[] buffer = new byte[bufferSize];
   int count = 0;

   try
   {
      current = DateTime.Now;
      dstFile = AppDomain.CurrentDomain.BaseDirectory + "\\"
         + current.Day.ToString() + current.Month.ToString()
         + current.Year.ToString() + current.Hour.ToString()
         + current.Minute.ToString() + current.Second.ToString()
         + ".cs";
      fsInFile = new FileStream(strFIlePath, FileMode.Open,
         FileAccess.Read, FileShare.Read);
      fsOutFile = new FileStream(dstFile, FileMode.Create,
         FileAccess.Write, FileShare.None);
      Myrar = new GZipStream(fsInFile,
         CompressionMode.Decompress, true);
      while (true)
      {
         count = Myrar.Read(buffer, 0, bufferSize);
         if (count != 0)
         {
            fsOutFile.Write(buffer, 0, count);
         }
         if (count != bufferSize)
         {
            // Have reached the end
            break;
         }
      }
   }

   catch (Exception ex)
   {
      // Handle or display the error
      System.Diagnostics.Debug.Assert(false, ex.ToString());
   }
   finally
   {
      if (Myrar != null)
      {
         Myrar.Close();
         Myrar = null;
      }
      if (fsOutFile != null)
      {
         fsOutFile.Close();
         fsOutFile = null;
      }
      if (fsInFile != null)
      {
         fsInFile.Close();
         fsInFile = null;
      }
   }
}

Finally, both the CompressFiles and DecompressFiles functions are called from the Main () method.

static void Main(string[] args)
{
   CompressFiles("C:\\Tapas\\PrjCompressDecompress\\
      PrjCompressDecompress\\Program.cs");
   DecompressFiles("C:\\Tapas\\PrjCompressDecompress\\
      PrjCompressDecompress\\bin\\Debug\\Request278201873627.rar");

}

Creating a .zip File

In the following example, I have shown how to create and extract a compressed file that has a .zip file extension by using the ZipFile class. To use the ZipFile class, I have added the reference of the System.IO.Compression.FileSystem assembly in my console project.

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;

namespace PrjCompressDecompress
{
   class Program
   {
      static void Main(string[] args)
      {
         string FilePath = "C:\\Tapas\\PrjCompressDecompress\\
            PrjCompressDecompress\\Program.cs";
         string zipFilePath = "C:\\Tapas\\PrjCompressDecompress\\
            PrjCompressDecompress\\Program.cs\\output.zip";
         string zipFilePath = "C:\\Tapas\\PrjCompressDecompress\\
            PrjCompressDecompress\\extract";
         ZipFile.CreateFromDirectory(FilePath, zipFilePath);
         ZipFile.ExtractToDirectory(zipFilePath, zipFilePath);
      }

   }
}

In the following code snippet, I have used the ZipArchive class to access an existing .zip file created in the previous step, and added a new help file to the existing compressed file. Finally, I have added it to the existing .zip file.

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;


namespace PrjCompressDecompress
{
   class Program
   {
      static void Main(string[] args)
      {
         using (FileStream myzipfile = new FileStream("C:\\Tapas\\
            PrjCompressDecompress\\PrjCompressDecompress\\
            Program.cs\\output.zip", FileMode.Open))
         {
            using (ZipArchive myzipfilearchive = new
               ZipArchive(myzipfile, ZipArchiveMode.Update))
            {
               ZipArchiveEntry helpfile = myzipfilearchive
                  .CreateEntry("helpfile.doc");
               using (StreamWriter writer = new
                  StreamWriter(helpfile.Open()))
               {
                  writer.WriteLine("Helpfile created for the
                     program.");
                  writer.WriteLine("End of the help file.");
               }
            }
         }

      }
   }
}

Conclusion

I hope the details and code snippets mentioned in this article will help you to understand the Compression and Decompression features of .NET. That’s all for today. Happy coding!

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read