Jan 29 2009

C# Comprimir y descomprimir un String (GZipStream)

Category: ProgramacionIndigo @ 11:05 PM

La verdad es que hace tiempo que no escribo nada en el blog, pero es que he estado bastante liado. Una de las últimas cosas que he tenido que hacer es comprimir un xml antes de guardarlo a disco ya que este ocupaba más de 5 megas y no era cuestión de tener ese espacio ocupado “inútilmente”. Aunque visto al precio que esta el MB o el GB podría evitarme estas molestias. La primera idea sería usar un compresor externo vía línea de comandos para comprimir esa cadena de texto. Como es lógico esta opción es muy poco viable. Otra solución sería implementar nosotros mismos un algoritmo de compresión y descompresión. Esta opción sería bastante interesante si quisiéramos pasar algo de tiempo aprendiendo sobre algoritmos de compresión, pero como no es el caso, también queda descartada. Ya sólo nos queda la opción de buscar algo dentro del framework de .NET y como suele ocurrir casi siempre, el framework nos trae una clase para esta tarea. En concreto es la clase GZipStream de la cual podemos leer mas información aquí.

El código para comprimir es el siguiente

   1: public static string Zip(string text)
   2: {
   3:     byte[] buffer = Encoding.UTF8.GetBytes(text);
   4:     MemoryStream ms = new MemoryStream();
   5:     using (GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true))
   6:     {
   7:         zip.Write(buffer, 0, buffer.Length);
   8:     }
   9:
  10:     ms.Position = 0;
  11:     MemoryStream outStream = new MemoryStream();
  12:
  13:     byte[] compressed = new byte[ms.Length];
  14:     ms.Read(compressed, 0, compressed.Length);
  15:
  16:     byte[] gzBuffer = new byte[compressed.Length + 4];
  17:     System.Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length);
  18:     System.Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzBuffer, 0, 4);
  19:     return Convert.ToBase64String(gzBuffer);
  20: }

y el código para descomprimir es muy parecido

   1: public static string UnZip(string compressedText)
   2: {
   3:     byte[] gzBuffer = Convert.FromBase64String(compressedText);
   4:     using (MemoryStream ms = new MemoryStream())
   5:     {
   6:         int msgLength = BitConverter.ToInt32(gzBuffer, 0);
   7:         ms.Write(gzBuffer, 4, gzBuffer.Length - 4);
   8:
   9:         byte[] buffer = new byte[msgLength];
  10:
  11:         ms.Position = 0;
  12:         using (GZipStream zip = new GZipStream(ms, CompressionMode.Decompress))
  13:         {
  14:             zip.Read(buffer, 0, buffer.Length);
  15:         }
  16:
  17:         return Encoding.UTF8.GetString(buffer);
  18:     }
  19: }

Como vemos el código es bastante simple y nos sirve para evitar que nuestros ficheros auxiliares crezcan de manera incontrolada.

Saludos y nos vemos en la próxima entrega.

¡Compartelo!
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Add to favorites
  • BarraPunto
  • Bitacoras.com
  • LinkedIn
  • Meneame
  • RSS
  • Technorati
  • Twitter

Tags: , , ,

3 Responses to “C# Comprimir y descomprimir un String (GZipStream)”

  1. rickyah says:

    Otra opción sería sharpzip, de los creadores de sharpdevelop, más interesante en el caso de que si se quiera aprender sobre algoritmos de compresión al ser libre y tener el fuente disponible ;)

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

  2. Indigo says:

    Muchas gracias por el comentarío… Cuando tenga un rato le echaré un vistazo.

  3. Perverso111 says:

    Hola amigo,

    muy util, gracias.

    Una pequeña observacion, creo que está linea sobra o me equivoco?

    11: MemoryStream outStream = new MemoryStream();

    Saludos