Aprieta, aprieta, que entra más…

No os llevéis a confusión con el título… Este artículo no es más que un mini-tutorial sobre la clase System.IO.Compression.GZipStream, que nos proporciona la funcionalidad necesaria para comprimir datos utilizando el estándar “de facto” gzip.

La verdad es que el uso de esta clase no debería ser complicado, ya que básicamente lo que hacemos es leer y escribir datos de un stream, como si fuese un fichero o un trozo de memoria más. Pero tiene una pequeña particularidad: Para que funcione correctamente nuestro código tenemos que tener cuidado de indicar en el constructor que queremos que el stream subyacente a nuestro GZipStream se quede abierto cuando terminemos de utilizarlo. Sobre todo cuando lo que queremos es comprimir en memoria, para posteriormente, sin crear ficheros temporales en el disco duro, enviarlo por red.

Veamos el ejemplo, sencillo, sencillo:

Para comprimir:

   Dim memStream As New System.IO.MemoryStream
   ' Aquí está el quid de la cuestión: Indicarle en el tercer parámetro
   ' que cuando cierre el stream de compresión, no elimine el stream
   ' subyacente.
   Dim gzip As New System.IO.Compression.GZipStream(memStream, _
                   IO.Compression.CompressionMode.Compress, True)
   Dim fileBytes() As Byte
   Dim compressedFileBytes() As Byte = {}
 
   ' Leemos el contenido del fichero a comprimir
   fileBytes = System.IO.File.ReadAllBytes(filePath)
   ' Escribimos en el stream compresor
   gzip.Write(fileBytes, 0, fileBytes.Length)
   ' Si no cerramos el stream, no podremos leer correctamente el 
   ' resultado de la compresión.
   gzip.Close()
 
   ' Vamos a leer los datos comprimidos
   Array.Resize(compressedFileBytes, memStream.Position)
   ' Colocamos el stream de memoria al inicio, para leer todo.
   memStream.Position = 0
   ' Ya tenemos todos los datos en el array compressedFileBytes.
   memStream.Read(compressedFileBytes, 0, compressedFileBytes.Length)
 
   ' Hacer lo que queramos con los bytes comprimidos...
 
   ' Y finalmente, limpiar un poquito.
   memStream.Close()
   gzip.Dispose()

Para descomprimir:

  ' fileBytes es un array de bytes que contiene el fichero comprimido
  Dim memStream As New System.IO.MemoryStream(fileBytes)
  ' Creamos el GZipStream basándonos en el stream de memoria.
  Dim gzip As New System.IO.Compression.GZipStream(memStream, _
                   IO.Compression.CompressionMode.Decompress)
  ' Si sabemos a priori el tamaño del fichero sin comprimir, 
  ' inicializamos el array de bytes que contendrá el fichero
  ' descomprimido.
  Dim realFileBytes(fileSize - 1) As Byte
 
  memStream.Position = 0
  
  ' Leemos el fichero.
  gzip.Read(realFileBytes, 0, fileSize)
  ' Cerramos...
  gzip.Close()
  gzip.Dispose()
 
  ' Usamos el fichero para lo que queramos, está en el memoryStream...
 
  ' Cerramos el MemoryStream.
  memStream.Close()

Saludos!

Un comentario en “Aprieta, aprieta, que entra más…”

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *