recomendar una biblioteca / API para descomprimir un archivo en C #

Parece que no hay biblioteca / API incorporada en C # para descomprimir un archivo zip. Estoy buscando una biblioteca / API gratuita (mejor de código abierto) que pueda funcionar con .Net 3.5 + VSTS 2008 + C # para descomprimir un archivo zip y extraer todos los archivos en una carpeta específica.

¿Alguna biblioteca / API recomendada o muestras?

La GPL

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

O el menos restrictivo Ms-PL

http://www.codeplex.com/DotNetZip

Para completar esta respuesta, el .NET Framework tiene ZipPackage , tuve menos éxito con él.

Si todo lo que quiere hacer es descomprimir el contenido de un archivo en una carpeta y sabe que solo se ejecutará en Windows, puede usar el objeto Shell de Windows. He utilizado la dynamic de Framework 4.0 en este ejemplo, pero puede lograr los mismos resultados utilizando Type.InvokeMember .

 dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application")); dynamic compressedFolderContents = shellApplication.NameSpace(sourceFile).Items; dynamic destinationFolder = shellApplication.NameSpace(destinationPath); destinationFolder.CopyHere(compressedFolderContents); 

Puede usar FILEOP_FLAGS para controlar el comportamiento del método CopyHere .

DotNetZip es fácil de usar. Aquí hay una muestra de descomprimir

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

Si tiene necesidades más complejas, como si desea escoger y elegir qué entradas extraer, o si hay contraseñas, o si desea controlar las rutas de acceso de los archivos extraídos, etc. etc., hay muchas opciones . Verifique el archivo de ayuda para más ejemplos.

DotNetZip es gratuito y de código abierto.

En el pasado, he usado DotNetZip (MS-PL), SharpZipLib (GPL) y el 7ZIP SDK para C # (dominio público). Todos funcionan muy bien, y son de código abierto.

Elegiría DotNetZip en esta situación, y aquí hay un código de muestra de la página de ejemplos de C # :

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

Eche un vistazo a mi pequeña biblioteca: http://zipstorer.codeplex.com

Si desea usar la compresión 7-zip, consulte el artículo EggheadCafe de Peter Bromberg. Cuidado: el código fuente LZMA para c # no tiene comentarios xml (en realidad, muy pocos comentarios).

Si no quiere usar un componente externo, aquí hay un código que desarrollé anoche usando la clase ZipPackage de .NET.

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

Cosas a tener en cuenta:

  • El archivo ZIP DEBE tener un archivo [Content_Types] .xml en su raíz. Esto no fue un problema para mis requisitos, ya que controlaré el ajuste de cualquier archivo ZIP que se extraiga a través de este código. Para obtener más información sobre el archivo [Content_Types] .xml, consulte: http://msdn.microsoft.com/en-us/magazine/cc163372.aspx. Hay un archivo de ejemplo debajo de la figura 13 del artículo.

  • No he probado el método CopyStream para garantizar que se comporta correctamente, ya que originalmente desarrollé esto para .NET 4.0 utilizando el método Stream.CopyTo ().

  #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 

Preferiría SharpZiplib. Encuentra el código de muestra para descomprimir archivos en .Net C #

Recomendaría nuestro http://www.rebex.net/zip.net/ pero soy parcial. Descarga la versión de prueba y comprueba las características y las muestras tú mismo.

SevenZipSharp es un envoltorio alrededor de 7z.dll y LZMA SDK, que es de código abierto y gratuito.

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