Archivos zip en C#

El framework .NET no incluye ninguna clase para trabajar con archivos zip fácilmente. Sí, desde la versión 3.0 tenemos disponible el espacio de nombres System.IO.Packaging, pero este no está pensado realmente para trabajar con archivos zip genéricos, sino con zips que siguen el formato Office Open XML de Microsoft (docx, pptx, xlsx, …).

Tampoco puedes usar (directamente) las clases GZipStream y DeflateStream del espacio de nombres System.IO.Compression ya que estas clases, introducidas en la versión 2.0 del framework, pese a lo que alguno pudiera pensar, no sirven para trabajar con archivos zip, sino con GZip y con el algoritmo Deflate.

Tenemos la opción de utilizar la API Windows Shell y aprovecharnos de la capacidad de las últimas versiones de Windows de trabajar con archivos ZIP, pero esto es un “hack” muy poco elegante, poco funcional, y que requiere de que el usuario utilice Windows XP o superior.

Otra solución que algunas personas proponen es usar el espacio de nombres java.util.zip de J# (Java puede trabajar con archivos ZIP de forma decente desde su versión 1.1) pero claro: no tiene nada que ver con C#, es poco funcional, implica unas enormes dependencias y J# está prácticamente muerto.

Visto lo visto lo mejor es acudir a las librerías de terceras partes. En este apartado tenemos varias opciones, de entre las cuales mi preferida es la librería DotNetZip. Otras alternativas son Xceed Zip for .NET, bastante interesante, pero con un precio de 399.95$ y SharpZipLib también muy buena, pero un poco más complicada de utilizar que DotNetZip.

Para poder utilizar DotNetZip primero descargamos el zip de la versión runtime desde su página web, descomprimimos, y copiamos la dll de la versión reducida a la carpeta de nuestro proyecto. En Visual Studio nos dirigimos al “Explorador de soluciones” y hacemos clic con el botón derecho sobre “References”, donde seleccionamos “Agregar referencia”. En la pestaña “Examinar” seleccionamos la dll de DotNetZip (Ionic.Zip.Reduced.dll). Una vez hecho esto podremos utilizar el namespace Ionic.Zip en nuestra aplicación.

El uso de DotNetZip es de lo más sencillo. Para crear un zip, por ejemplo, haríamos algo como lo siguiente:

using Ionic.Zip;

namespace EjemploZip {
    class Program {
        static void Main(string[] args) {
            ZipFile zip = new ZipFile();

            zip.AddFile("d:\\imagen.png", "");
            zip.AddFile("d:\\texto.txt", "");
            zip.AddFile("d:\\musica.mp3", "");

            zip.Save("c:\\archivo.zip");
        }
    }
}

O bien, para añadir varios archivos con una sola llamada:

using Ionic.Zip;

namespace EjemploZip {
    class Program {
        static void Main(string[] args) {
            string archivos[] = {"d:\\imagen.png", "d:\\texto.txt", "d:\\musica.mp3"};
            
            ZipFile zip = new ZipFile();

						AddFiles(archivos);

            zip.Save("c:\\archivo.zip");
        }
    }
}

Para extraer el contenido de un archivo:

using Ionic.Zip;

namespace EjemploZip {
    class Program {
        static void Main(string[] args) {
            ZipFile zip = ZipFile.Read("d:\\archivo.zip");

            foreach (ZipEntry f in zip)
                f.Extract("d:\\", ExtractExistingFileAction.OverwriteSilently);
        }
    }
}

Si necesitas más ejemplos también puedes echar un vistazo a la sección correspondiente de su página web, muy bien documentada, en Ejemplos de DotNetZip en C#.



Comentarios
  1. Licenciada bajo la ¡Micro$oft! Public License, con pocas restricciones y relicenciable bajo la GNU GPL. Por eso sería que no pude compilar bien el programa, la biblioteca no venía :P.

    Por cierto… ¿en C# se pueden usar variables como %windir%?

    Responder

    • Ah, pues sí, seguramente, porque es la librería que utilicé.

      Puedes obtener el valor de cualquier variable de entorno con System.Environment.GetEnvironmentVariable()

      Responder

      • OK, algún día me pondré con ello en serio…

        ¿Y para variables de usuario cómo es?

        Responder

    • Hola a todos.
      Por favor revisen mi libreria ZipStorer en http://zipstorer.codeplex.com
      Es muy pequeña y usa internamente la clase DeflateStream de .net
      Puede guardar y recuperar archivos de un archivo .zip en forma comprimida (deflate) o sin comprimir.
      Saludos,
      Jaime.

      Responder

  2. En Python 2.6 ya viene incluído un módulo para manejo de archivos zip.

    Ejemplo de creación de un archivo zip:

    import zipfile

    zfile = zipfile.ZipFile(‘archivo.zip’, ‘w’)
    zfile.write(‘imagen.png’)
    zfile.write(‘texto.txt’)
    zfile.write(‘musica.mp3’)
    zfile.close()

    Ejemplo de extracción de todos los archivos de un zip:

    zfile = zipfile.ZipFile(‘archivo.zip’, ‘r’)
    zfile.extractall()
    zfile.close()

    Saludos!

    Responder

  3. menek

    Y DotNetZip funciona sin problemas en Mono.

    Responder

  4. Jordi

    No me preguntéis como funciona, pues lo use hace un montón de tiempo y ya ni me acuerdo (se que es muy fácil y que lo tengo en una dll..)
    http://www.info-zip.org/

    Responder

  5. Korso

    ¿Por casualidad no conoceréis algo equivalente (y así de sencillo) para c++? Con que comprima en *.zip un archivo me sobra.

    Responder

    • Hombre, para eso incluye código de 7-zip, de Igor Pavlov. O usa la dll. Todo GNU LGPL, excepto el módulo de rar, que es privativo.

      Y lo de así de sencillo… a ver, por algo llaman a C# lenguaje de alto nivel y a C++ de medio nivel 🙂

      Responder

  6. Jordi

    Buscad INFO-ZIP en Google y su dll ZIP.dll …. Una maravilla oiga 😉

    Responder

  7. Lo dicho, me esta seduciendo el C#

    Responder

Deja un comentario