48

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?

0

11 Answers 11

35

The GPL

http://www.icsharpcode.net/OpenSource/SharpZipLib/

OR the less restrictive Ms-PL

http://www.codeplex.com/DotNetZip

To complete this answer the .net framework has ZipPackage I had less success with it.

Sign up to request clarification or add additional context in comments.

8 Comments

as well .Net has a built in implementation, but its impossible to work with
Cool I like the first one. For the .Net one, which class do you mean?
In most cases, DotNetZip is considerably simpler to use that SharpZipLib.
@Cheeso: True, but SharpZipLib supports more file formats, such as tar.
True, but if you need a tar library, use a tar library. The format is very much simpler than zip. There's a single-file tar library for .NET: stackoverflow.com/questions/391936/…
|
24

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.

2 Comments

By far THE MOST stinkin' awesome answer to this age-old-question! This needs major upvoting.
I have to agree with @joshuam...
17

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.

Comments

10

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); } } 

4 Comments

LGPL, not GPL - the difference is quite big.
@Quandary which one? SharpZipLib is GPL, according to their web site.
GPL with that exception (linking it statically or dynamically with your project is not derived work under the GPL) = LGPL (ok, permission to link statically is not in the LGPL, that's why they write it like this, but statically linking is unusual for .NET). Frankly, it's a more liberal version of the LGPL.
No, the LGPL comes with extra rules compared to GPL+exception, like that you need to provide object files so the user can re-link the application with a customized variant of the LGPL'ed library.
7

SharpZipLib

http://www.icsharpcode.net/OpenSource/SharpZipLib/

1 Comment

How do you think of .Net's built ZipPackage class?
5

Have a look to my small library: https://github.com/jaime-olivares/zipstorer

1 Comment

This is actually the best answer!
2

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).

Comments

1

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.

Comments

1
 #region CreateZipFile public void StartZip(string directory, string zipfile_path) { Label1.Text = "Please wait, taking backup"; #region Taking files from root Folder string[] filenames = Directory.GetFiles(directory); // path which the zip file built in ZipOutputStream p = new ZipOutputStream(File.Create(zipfile_path)); foreach (string filename in filenames) { FileStream fs = File.OpenRead(filename); byte[] buffer = new byte[fs.Length]; fs.Read(buffer, 0, buffer.Length); ZipEntry entry = new ZipEntry(filename); p.PutNextEntry(entry); p.Write(buffer, 0 , buffer.Length); fs.Close(); } #endregion string dirName= string.Empty; #region Taking folders from root folder DirectoryInfo[] DI = new DirectoryInfo(directory).GetDirectories("*.*", SearchOption.AllDirectories); foreach (DirectoryInfo D1 in DI) { // the directory you need to zip filenames = Directory.GetFiles(D1.FullName); if (D1.ToString() == "backup") { filenames = null; continue; } if (dirName == string.Empty) { if (D1.ToString() == "updates" || (D1.Parent).ToString() == "updates" || (D1.Parent).Parent.ToString() == "updates" || ((D1.Parent).Parent).Parent.ToString() == "updates" || (((D1.Parent).Parent).Parent).ToString() == "updates" || ((((D1.Parent).Parent).Parent)).ToString() == "updates") { dirName = D1.ToString(); filenames = null; continue; } } else { if (D1.ToString() == dirName) ; } foreach (string filename in filenames) { FileStream fs = File.OpenRead(filename); byte[] buffer = new byte[fs.Length]; fs.Read(buffer, 0, buffer.Length); ZipEntry entry = new ZipEntry(filename); p.PutNextEntry(entry); p.Write(buffer, 0, buffer.Length); fs.Close(); } filenames = null; } p.SetLevel(5); p.Finish(); p.Close(); #endregion } #endregion #region EXTRACT THE ZIP FILE public bool UnZipFile(string InputPathOfZipFile, string FileName) { bool ret = true; Label1.Text = "Please wait, extracting downloaded file"; string zipDirectory = string.Empty; try { #region If Folder already exist Delete it if (Directory.Exists(Server.MapPath("~/updates/" + FileName))) // server data field { String[] files = Directory.GetFiles(Server.MapPath("~/updates/" + FileName));//server data field foreach (var file in files) File.Delete(file); Directory.Delete(Server.MapPath("~/updates/" + FileName), true);//server data field } #endregion if (File.Exists(InputPathOfZipFile)) { string baseDirectory = Path.GetDirectoryName(InputPathOfZipFile); using (ZipInputStream ZipStream = new ZipInputStream(File.OpenRead(InputPathOfZipFile))) { ZipEntry theEntry; while ((theEntry = ZipStream.GetNextEntry()) != null) { if (theEntry.IsFile) { if (theEntry.Name != "") { string directoryName = theEntry.Name.Substring(theEntry.Name.IndexOf(FileName)); // server data field string[] DirectorySplit = directoryName.Split('\\'); for (int i = 0; i < DirectorySplit.Length - 1; i++) { if (zipDirectory != null || zipDirectory != "") zipDirectory = zipDirectory + @"\" + DirectorySplit[i]; else zipDirectory = zipDirectory + DirectorySplit[i]; } string first = Server.MapPath("~/updates") + @"\" + zipDirectory; if (!Directory.Exists(first)) Directory.CreateDirectory(first); string strNewFile = @"" + baseDirectory + @"\" + directoryName; if (File.Exists(strNewFile)) { continue; } zipDirectory = string.Empty; using (FileStream streamWriter = File.Create(strNewFile)) { int size = 2048; byte[] data = new byte[2048]; while (true) { size = ZipStream.Read(data, 0, data.Length); if (size > 0) streamWriter.Write(data, 0, size); else break; } streamWriter.Close(); } } } else if (theEntry.IsDirectory) { string strNewDirectory = @"" + baseDirectory + @"\" + theEntry.Name; if (!Directory.Exists(strNewDirectory)) { Directory.CreateDirectory(strNewDirectory); } } } ZipStream.Close(); } } } catch (Exception ex) { ret = false; } return ret; } #endregion 

Comments

0

I would recommend our http://www.rebex.net/zip.net/ but I'm biased. Download trial and check the features and samples yourself.

Comments

0

SevenZipSharp is a wrapper around tha 7z.dll and LZMA SDK, which is Open-source, and free.

SevenZipCompressor compressor = new SevenZipCompressor(); compressor.CompressionLevel = CompressionLevel.Ultra; compressor.CompressionMethod = CompressionMethod.Lzma; compressor.CompressionMode = CompressionMode.Create; compressor.CompressFiles(...); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.