martes, 21 de febrero de 2012

Comprimir archivos a ZIP en Visual Basic .NET

En estos días me he visto en la necesidad de buscar una forma de comprimir a un ZIP un archivo de texto, lo cual es algo no muy simple, por lo que he podido ver.

Me puse manos a la obra y exploré las soluciones que se me ofrecían (la mayoría, de pago), pero, como todos sabemos, "... el que buscare, encontrará".

La solución que encontré se llama DotNetZip Library, y no es más que una librería y set de herramientas gratuito publicado por la comunidad de open source CodePlex, la cual se rige por la licencia Microsoft Public License.

Entonces, vamos a lo que nos interesa: ¿Cómo se comprime un archivo?

Con esta librería he encontrado que se hace de una forma muy simple; lo primero que necesitamos es bajarnos la librería DotNetZip, y luego, vamos a buscar dentro del zip que bajamos, el siguiente archivo: zip-v1.9\Release\Ionic.Zip.dll, el cual descomprimiremos en cualquier lugar de nuestro sistema.

Hecho esto, en Visual Studio hemos de crear un nuevo proyecto, nombrarlo como deseemos y hacer lo siguiente:

  1. Añadir una referencia a Ionic.Zip.dll: En el explorador del proyecto, click derecho y seleccionar la opción "Agregar referencia" o "Add reference" en el caso de que esté en inglés.
  2. Importar el namespace: Tecleamos en el area de imports de nuestro proyecto lo siguiente: Imports Ionic.Zip
Ahora, el código:


Imports Ionic.Zip

    Private Sub Comprimir()
       Using zip As ZipFile = New ZipFile()
           zip.AddFile("rutaarchivo\nombrearchivo1.ext","")
           zip.AddFile("rutaarchivo\nombrearchivo2.ext","")
           zip.Save("rutazip\nombrezip.zip")
       End Using
    End Sub

Como podrán ver, la forma de hacerlo es muy sencilla, simplemente se utiliza el método "AddFile" del objeto zip de tipo ZipFile para añadir cuantos archivos necesitemos comprimir, y luego se guarda el Zip con el método "Save"; ahora bien, podemos observar que AddFile tiene un segundo parámetro el cual es un string en blanco. ¿Qué siginifica? Pues, simplemente es una ruta que se utilizará dentro del ZIP; por ejemplo, si la instrucción fuera:

           zip.AddFile("rutaarchivo\nombrearchivo.ext","test\")

entonces, al abrir el zip resultante, tendríamos primero una carpeta llamada "test" dentro de la cual estaría almacenado el archivo.
Por lo tanto, como el segundo parámetro es una cadena vacía, se le indica a la clase que quiere que no haya ninguna estructura de directorios dentro del Zip, simplemente el archivo en cuestión; por defecto, si no se especifica este parámetro, el método creará la estructura de directorios original del archivo dentro del ZIP.

Para más información de cómo utilizar esta librería, pueden visitar su documentación oficial (en inglés), donde podrán encontrar la referencia de los espacios de nombres, clases, etc. y una sección con bastantes ejemplos (como comprimir de forma simple o incluso agregando una contraseña, descomprimir, etc.) en cada lenguaje con el que se puede utilizar.

 Espero les sea de utilidad esta información.

Saludos.

16 comentarios:

  1. Amigo muchas gracias por tu post.
    Mi pregunta es la siguiente.
    cuando trato de guardar el archivo .zip "zip.Save("rutazip\nombrezip.zip")"
    no lo guarda en la ruta que yo le especifiqué, si no que por defecto lo crea y lo guarda en la ruta:
    C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0

    Sabes como puedo asignarle la ruta donde lo quiero guardar?

    ResponderEliminar
    Respuestas
    1. Buenas amigo.
      ¿Asignaste la ruta completa? es decir, ¿colocaste en el programa algo como "zip.Save("C:\ruta\completa\nombrezip.zip")"? todo debe ir con la ruta completa, porque con rutas relativas siempre va a tomar como base el directorio donde se encuentre el ejecutable ya compilado que estés corriendo.

      Eliminar
  2. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  3. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  4. Gracias por el aporte! Disculpa una duda:

    Private Sub Comprimir()
    Using zip As ZipFile = New ZipFile()
    zip.AddFile(Me.TextBox1.Text, "")
    zip.Save(Me.TextBox1.Text & ".zip")
    End Using
    End Sub

    Private Sub btarchivo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btArchivo.Click
    OpenFileDialog1.Title = "Seleccione un archivo"
    OpenFileDialog1.InitialDirectory = "C:temp"

    OpenFileDialog1.ShowDialog()

    End Sub

    Private Sub OpenFileDialog1_FileOk(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles OpenFileDialog1.FileOk

    Dim strm As System.IO.Stream
    strm = OpenFileDialog1.OpenFile()
    TextBox1.Text = OpenFileDialog1.FileName.ToString()

    If Not (strm Is Nothing) Then
    'insert code to read the file data
    strm.Close()
    MessageBox.Show("Archivo Seleccionado")
    End If
    End Sub

    Uso ese codigo para que el usuario seleccione el archivo y posteriormente al comprimirlo lo comprime con exito pero por decir si el archivo es .txt y se llama Prueba
    al comprimirlo queda:

    Prueba.txt.zip

    Si lo comprime bien y si funciona pero mi duda es como quitarle al extension al nombre y solo quede como:
    Prueba.zip ...

    ResponderEliminar
    Respuestas
    1. mmm... podrías utilizar las funciones instr y substring, algo así:

      zip.Save(Me.TextBox1.Text.Substring(1,Instr(Me.TextBox1.Text,".")) & ".zip")

      Esta sentencia
      Me.TextBox1.Text.Substring(1,Instr(Me.TextBox1.Text,"."))
      Lo que haría es obtener la subcadena que esté antes o hasta el punto. pruebala, y si te sale el punto, simplemente tienes que restarle uno a lo que devuelve el Instr, así:

      Me.TextBox1.Text.Substring(1,Instr(Me.TextBox1.Text,".") - 1)

      Saludos.

      Eliminar
    2. Otra posible solución que podrías usar (yo no lo he probado) es el uso de una función de .NET:

      System.IO.Path.GetFileNameWithoutExtension(file)

      Puedes ver la información técnica y un ejemplo de este método aquí:

      http://msdn.microsoft.com/en-us/library/system.io.path.getfilenamewithoutextension.aspx

      entonces me imagino que se ha de utilizar algo así:

      System.IO.Path.GetFileNameWithoutExtension(Me.TextBox1.Text)

      Se ve más confiable porque ha de identificar correctamente la extensión del archivo.

      Saludos.

      Eliminar
  5. Excelente post muchas gracias ahora mis sistemas de informacion estaran mucho mas completas gracias

    ResponderEliminar
  6. pero tengo una duda. al guardas como .zip, que ruta debería de ir podría ser la de mi archivo en Excel el que quiero comprimir?

    ResponderEliminar
  7. Hola Evelyn.

    Bueno, tenemos la instrucción

    zip.AddFile("rutaarchivo\nombrearchivo.ext","test\")

    Donde "rutaarchivo\nombrearchivo.ext" es tu archivo de excel. Si estuviera en C: y se llamara MiArchivoExcel.xls, sería "C:\MiArchivoExcel.xls".

    El segundo parámetro sólo es una ruta interna para el zip, por ejemplo, si quisiera que al descomprimir, saliera una carpeta llamada "carpeta", sería "carpeta\"; ahora, si quisiera que dentro de mi carpeta "carpeta" hubiera otra carpeta que se llame "archivos" y allí estuviera mi archivo excel, entonces sería "carpeta\archivos\". En este último caso, la llamada quedaría así:


    zip.AddFile("C:\MiArchivoExcel.xls","carpeta\archivos\")

    Ahora si quiero que solo vaya el archivo, envío una cadena en blanco en el segundo parámetro:

    zip.AddFile("C:\MiArchivoExcel.xls","")

    Espero se entienda.

    Saludos.

    ResponderEliminar
  8. Ejemplo para comprimir directorio:


    Using zip As ZipFile = New ZipFile()

    zip.AddDirectory("W:\Prueba")
    zip.Save("W:\Prueba.zip")
    End Using

    ResponderEliminar
  9. Muy buen Post, muchas gracias por tu aporte

    ResponderEliminar
  10. Gracias por toda la información. Eres muy gentíl.
    Un saludo especial desde Bogotá,Colombia

    ResponderEliminar