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