Sunday, March 24, 2013

How to extract a ZIP or RAR file in C#

The .NET framework has some archives functionality with the deflate class, but i found that it's not versatile enough, and it's a bit of a pain to use.
There's a lot of libraries that enables you to handle archive files in an easy way, personally i found that SharpCompress is the best. It's small, open source, it works well and the author is a great guy. Reading the documentation is enough to learn how to extract everything. To start using it you need to add a reference to the sharpcompress.dll in your project, you can do that by:
Right click on the project name in Visual Studio -> Add reference -> Browse -> Select the .dll from the folder you saved it in.
Once you do that, you can start using the library by telling your program what you want to use. You should already know how, but here's what you need for this method to work.
using SharpCompress.Common;
using SharpCompress.Archive;
After you do that you're ready to extract some files, the method is really simple, you just tell SharpCompress which file you want to extract, and you cycle through every file in the archive to save it to a directory.
private void extractArchive(string dir, string file) 
{
    var compressed = ArchiveFactory.Open(@file);
                    
    foreach (var entry in compressed.Entries)
    {
        if (!entry.IsDirectory)
        {
            entry.WriteToDirectory(@dir, ExtractOptions.ExtractFullPath | ExtractOptions.Overwrite);
        }
    }
}
This would be enough to extract archives, but it doesn't show you the progress, and the user would be presented with a stalled UI if you don't run the code in a separate thread. I'm not gonna cover multithreading right now, but a simple progress bar would be a really nice addition for the users. Implementing a progress bar in C# is really easy, you just create the object, put it wherever you want, set a maximum amount and at every iteration of the cycle you increment the progress bar value by one. I'm gonna show a simple example of a progress bar that will be showed at the center of the form when you extract a file:
using SharpCompress.Common;
using SharpCompress.Archive;

private void extractArchive(string dir, string file) 
{
    var compressed = ArchiveFactory.Open(@file);
    //Creates the ProgressBar object
    ProgressBar bar = new ProgressBar();
    //Assing the ProgressBar dimensions, change it however you like
    bar.Height = 50;
    bar.Width = 200;
    //Set the ProgressBar location, in this case in the center form
    bar.Location = new Point(this.Width / 2 - bar.Width / 2, this.Height / 2 - bar.Height / 2);
    //Set the maximum value for the ProgressBar
    bar.Maximum = compressed.Entries.Count() * 10;
    //Add the ProgressBar to the form controls
    this.Controls.Add(bar);

    foreach (var entry in compressed.Entries)
    {
        if (!entry.IsDirectory)
        {
            entry.WriteToDirectory(@dir, ExtractOptions.ExtractFullPath | ExtractOptions.Overwrite);
        }
        //Increment the ProgressBar value by 1
        bar.PerformStep();
    }
    //Remove the ProgressBar from the form and dispose
    this.Controls.Remove(bar);
    bar.Dispose();
}
You can obviously change the ExtractOptions to whatever will suit your needs.

2 comments:

  1. Hello, I have implemented this and it works for me, but I find it very slow. If I extract the Zip I am using manually it takes about 45 seconds. When I run it this was it took 4 minutes and 45 seconds. Also, when I use System.IO.Compression.ZipFile.ExtractToDirectory it is much faster. Have you run into this at all?

    ReplyDelete
  2. sir it shows error in code at:
    ProgressBar bar = new ProgressBar();

    ReplyDelete

prettyprint