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:
- RAR
- 7Zip
- Zip
- Tar
- BZip2
- GZip
Currently it able to write archive in these formats:
- Zip
- Tar
- BZip2
- GZip
The following are not yet supported, and it’s in To-Do list:
- RAR 5
- Write 7Zip
- Zip64
- 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!
loading...
About Hardono
Incoming Search
.net, c#, compression

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