2014
11.27

I’ve came across a number of compression libraries in .NET world. At first, I used DotNetZip. DotNetZip supports only Zip format. But it was sufficient. Later, I found SharpZipLib. SharpZipLib supports more format such as Gzip, Tar and Bzip2.

SharpCompress supersedes both of them. As of now, it able to extract these formats:

  1. RAR
  2. 7Zip
  3. Zip
  4. Tar
  5. BZip2
  6. GZip

Currently it able to write archive in these formats:

  1. Zip
  2. Tar
  3. BZip2
  4. GZip

The following are not yet supported, and it’s in To-Do list:

  1. RAR 5
  2. Write 7Zip
  3. Zip64
  4. Multi-volume Zip

To install SharpCompress, you can manually fork the repository from GitHub. Or you can use NuGet:

     PM > Install-Package SharpCompress

Import the reference:

using SharpCompress.Archive;
using SharpCompress.Common;

Opening archive:

//f is FileInfo object     
var archive = ArchiveFactory.Open(f);

Extracting archive content:

//Sort the entries before extracting
//This will help especially when the archive contain folders
var sortedEntries = archive.Entries.OrderBy(x=>x.FilePath.Length);
foreach (var entry in sortedEntries)
{
   if (entry.IsDirectory) {
      //Create subdirectory
   }
   else {
      //extract file
      entry.WriteToFile(File_Path_Destination, Extracting_Option);
   }
}

Here’s the complete example that I made recently. This program will iterate a directory, and all of its sub-directories, then extract any .RAR or .ZIP found.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using SharpCompress.Archive;
using SharpCompress.Common;

namespace ArchiveExtractor
{
    //Extension to allow us to filter files in a folder using multiple extensions
    static class MyExtension
    {
        public static IEnumerable<FileInfo> GetFilesByExtensions(this DirectoryInfo dir, params string[] extensions)
        {
            if (extensions == null)
                throw new ArgumentNullException("extensions");
            IEnumerable<FileInfo> files = dir.EnumerateFiles();
            return files.Where(f => extensions.Contains(f.Extension));
        }
    }
    class Program
    {
        //Dictionary to keep track which files already processed
        private static Dictionary<String, List<String>> _processDict;
        
        static void Main(string[] args)
        {
            _processDict = new Dictionary<string, List<string>>();
            //repeat until user decide to call quit
            while (true)
            {
                Console.Write("Directory to Process (x to Exit, Enter to process current directory): ");
                var cmd = Console.ReadLine();
                
                //Setup the initial directory
                DirectoryInfo curDir = null;
                if (String.IsNullOrEmpty(cmd))
                {
                    curDir = new DirectoryInfo(Directory.GetCurrentDirectory());
                }
                else if (cmd.ToLower() == "x")
                    return;
                else
                {
                    curDir = new DirectoryInfo(cmd);
                    if (!curDir.Exists)
                    {
                        Console.WriteLine("Invalid directory");
                        continue;
                    }
                }
                //Process the directory
                ProcessDirectory(curDir, "");
            }
        }

        private static void ProcessDirectory(DirectoryInfo dir, String prefix)
        {
            Console.WriteLine("{0}[{1}]", prefix, dir.FullName);
            _processDict.Add(dir.FullName, new List<string>());

            var subdirs = dir.GetDirectories();
            foreach (var subdir in subdirs)
            {
                //Recursively process the sub-directories
                ProcessDirectory(subdir,"   ");
            }
            //In case the .ZIP extracts to .RAR,
            //process the files twice
            ProcessFiles(dir,prefix);
            ProcessFiles(dir, prefix);
        }

        private static void ProcessFiles(DirectoryInfo dir, String prefix)
        {
            foreach (var f in dir.GetFilesByExtensions(".zip", ".rar"))
            {
                //have we processed this file before?
                if (!_processDict[dir.FullName].Contains(f.Name))
                {
                    Console.WriteLine("{0}  {1}",prefix, f.Name);
                    //nope, mark it as processed
                    _processDict[dir.FullName].Add(f.Name);

                    //open Archive
                    var archive = ArchiveFactory.Open(f);
                    //sort the entries
                    var sortedEntries = archive.Entries.OrderBy(x => x.FilePath.Length);
                    foreach (var entry in sortedEntries)
                    {
                        if (entry.IsDirectory && !Directory.Exists(dir.FullName + "\\" + entry.FilePath))
                        {
                            //create sub-directory 
                            dir.CreateSubdirectory(entry.FilePath);
                        }
                        else if  (!File.Exists(dir.FullName + "\\" + entry.FilePath))
                        {
                            //extract the file
                            entry.WriteToFile(dir.FullName + "\\" + entry.FilePath, ExtractOptions.Overwrite);
                        }
                    }
                }
            }
        }
    }
}

I hope it helps, cheers!

GD Star Rating
loading...
SharpCompress: Fully Managed .NET Compression Library, 4.0 out of 5 based on 2 ratings
Worth sharing ?

Incoming Search Term

Advertise Here

 

2 comments so far

Add Your Comment
  1. I am using SharpCompress nuget package to unzip files.

    There are few files that SharpCompress is unable to unzip.

    You can get the file from the link https://github.com/isagalaev/highlight.js/archive/8.9.1.tar.gz

    Below is the exception that I am getting:

    System.ArgumentNullException was unhandled
    HResult=-2147467261
    Message=Value cannot be null.
    Parameter name: path2
    ParamName=path2
    Source=mscorlib
    StackTrace:
    at System.IO.Path.Combine(String path1, String path2)
    at SharpCompress.Reader.IReaderExtensions.WriteEntryToDirectory(IReader reader, String destinationDirectory, ExtractOptions options)
    at Sharpcompress.Program.Main(String[] args) in E:2015ProjectsSharpcompressProgram.cs:line 24
    at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
    at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
    at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    at System.Threading.ThreadHelper.ThreadStart()
    InnerException:

    Any help on this.

    • Can you show me the line which the exception was thrown? E.g. 2015ProjectsSharpcompressProgram.cs:line 24