recommend a library/API to unzip file in C#

Viewed 29326

Looks like no built-in Library/API in C# to unzip a zip file. I am looking for a free (better open source) library/API which could work with .Net 3.5 + VSTS 2008 + C# to unzip a zip file and extract all files into a specific folder.

Any recommended library/API or samples?

11 Answers

If all you want to do is unzip the contents of a file to a folder, and you know you'll only be running on Windows, you can use the Windows Shell object. I've used dynamic from Framework 4.0 in this example, but you can achieve the same results using Type.InvokeMember.

dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));

dynamic compressedFolderContents = shellApplication.NameSpace(sourceFile).Items;
dynamic destinationFolder = shellApplication.NameSpace(destinationPath);

destinationFolder.CopyHere(compressedFolderContents);

You can use FILEOP_FLAGS to control behaviour of the CopyHere method.

DotNetZip is easy to use. Here's an unzip sample

using (var zip = Ionic.Zip.ZipFile.Read("archive.zip"))
{
   zip.ExtractAll("unpack-directory");
}

If you have more complex needs, like you want to pick-and-choose which entries to extract, or if there are passwords, or if you want to control the pathnames of the extracted files, or etc etc etc, there are lots of options. Check the help file for more examples.

DotNetZip is free and open source.

In the past, I've used DotNetZip (MS-PL), SharpZipLib (GPL), and the 7ZIP SDK for C# (public domain). They all work great, and are open source.

I would choose DotNetZip in this situation, and here's some sample code from the C# Examples page:

using (ZipFile zip = ZipFile.Read(ExistingZipFile))
{
  foreach (ZipEntry e in zip)
  {
    e.Extract(TargetDirectory);
  }
}

If you want to use 7-zip compression, check out Peter Bromberg's EggheadCafe article. Beware: the LZMA source code for c# has no xml comments (actually, very few comments at all).

If you do not want to use an external component, here is some code I developed last night using .NET's ZipPackage class.

private static void Unzip()
{
    var zipFilePath = "c:\\myfile.zip";
    var tempFolderPath = "c:\\unzipped";

    using (Package pkg = ZipPackage.Open(zipFilePath, FileMode.Open, FileAccess.Read))
    {
        foreach (PackagePart part in pkg.GetParts())
        {
            var target = Path.GetFullPath(Path.Combine(tempFolderPath, part.Uri.OriginalString.TrimStart('/')));
            var targetDir = target.Remove(target.LastIndexOf('\\'));

            if (!Directory.Exists(targetDir))
                Directory.CreateDirectory(targetDir);

            using (Stream source = part.GetStream(FileMode.Open, FileAccess.Read))
            {
                CopyStream(source, File.OpenWrite(target));
            }
        }
    }
}

private static void CopyStream(Stream input, Stream output)
{
    byte[] buffer = new byte[4096];
    int read;
    while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
    {
        output.Write(buffer, 0, read);
    }
} 

Things to note:

  • The ZIP archive MUST have a [Content_Types].xml file in its root. This was a non-issue for my requirements as I will control the zipping of any ZIP files that get extracted through this code. For more information on the [Content_Types].xml file, please refer to: http://msdn.microsoft.com/en-us/magazine/cc163372.aspx There is an example file below Figure 13 of the article.

  • I have not tested the CopyStream method to ensure it behaves correctly, as I originally developed this for .NET 4.0 using the Stream.CopyTo() method.

Related