System.IO.Compression.GZipStream (Clase)

Descripción general

Unas pocas líneas sobre la forma de comprimir un fichero usando únicamente código .NET. El resultado solo permite comprimir / descomprimir un fichero, (nada de comprimir / descomprimir directorios completos) y, evidentemente, no puede competir con las utilidades gratuitas de compresión, pero no deja de ser un interesante ejercicio de programación

[TOC] Tabla de Contenidos


System.IO.Compression.GZipStream (Clase)


↑↑↑

A modo de introducción

El otro día navegando por Internet, encontré un artículo que hablaba de comprimir un archivo,

Después de mirar un poco este asunto en la ayuda MSDN

y sin tener muy claras cual es la diferencia entre las dos clases, he escrito un par de funciones, una que comprime y otra que descomprime un solo fichero.

Realmente a nivel de usuario no es útil ya que existen un montón de programas gratuitos que facilitan la compresión de ficheros y directorios, mientras que la función que he escrito, solo comprime un único fichero. Pero no deja de ser un interesante ejercicio de programación


↑↑↑

Observaciones.:

En el espacio de nombres System.IO.Compression existen dos clases que podemos usar para realizar tareas de compresión. Esas dos clases son: GZipStream y DeflateStream. las formas de utilizarlas son prácticamente idénticas; solo tendremos que cambiar el nombre de la clase a usar cuando queramos realizar la compresión con una clase o con la otra. El resto del código es el mismo

La peculiaridad de estas dos clases es que solo trabajan con un fichero a la vez, y por tanto solo nos servirán para comprimir/descomprimir un solo fichero

¡¡¡Importante!!! En .NET existe la restricción de 4 Gigas en los archivos que comprimen / descomprimen estas clases

La clase DeflateStream usa el algoritmo de compresión "DEFLATE" que lo podemos encontrar detallado en el RFC 1951 (URL: http://www.faqs.org/rfcs/rfc1951.html) y que es libre sin patentes e implementado en muchas herramientas de compresión, en si se basa en la combinación del Algoritmo LZ77 y la codificación Huffman. ;( A modo de comentario.: el formato gráfico PNG utiliza el algoritmo Deflate para realizar la compresión.)

La clase GZipStream se basa también en el algoritmo de compresión DEFLATE agregándole ciertos metadatos tanto en la cabecera y un pie de página. Por lo mismo dentro del framework .NET se puede decir que GZipStream es una extensión de la clase Deflate, a la que se le ha agregado una cabecera y un pie de página para hacerla compatible con otros compresores / descompresores tal como es WinZip o Winrar

El formato incluye un valor de prueba cíclica de redundancia para detectar daños en los datos.

La funcionalidad de compresión GZipStream se expone como una secuencia (Stream). Los datos se leen byte a byte, por lo que no es posible realizar varios pases a fin de determinar el método más adecuado para comprimir archivos enteros o grandes bloques de datos.

Los objetos GZipStream comprimidos escritos en un archivo con la extensión .gz se pueden descomprimir con diversas herramientas de compresión comunes; sin embargo, de forma nativa, las clases de .NET, no proporcionan de forma inherente la funcionalidad para agregar o extraer archivos múltiples archivos en un archivo con formato .zip.

La clase GZipStream se utiliza de forma óptima orígenes de datos sin comprimir. Si los datos de origen ya están comprimidos, el uso de esta clase puede aumentar el tamaño de la secuencia. (Por ejemplo, un .gif crecerá de tamaño un 50%, es decir, el archivo comprimido resulta tener un tamaño del 150% del tamaño original sin comprimir),


↑↑↑

Un poco de código

''' <summary>
''' Comprime un archivo a otro en formato ZIP
''' </summary>
''' <param name="ficheroEntradaNormal"> 
''' <para>Tipo <see cref="FileInfo">FileInfo</see></para>
''' <para>El fichero que se quiere comprimir</para>
''' </param>
''' <param name="ficheroSalidaComprimido">
''' <para>Tipo <see cref="FileInfo">FileInfo</see></para>
''' <para>El resultado de la compresion, el fichero comprimido</para>
''' </param>
''' <returns>
''' <para>Tipo <see cref="Boolean">Boolean</see></para>
''' <para>La operacion de compresion ha tenido exito
    (true), o ha fallado (false). </para>
''' <para> TRUE : Si el porceso de compresion fue satisfactorio</para>
''' <para> FALSE: Si el porceso de compresion falla.
''' </para>
''' </returns>
''' <remarks>
''' <para> El codigo no realiza las siguientes comprobaciones
''' que hay que realizar como control de los parametros de entrada. 
''' </para>
''' <para> ** Fichero de Entrada Normal ** </para>
''' <para> -> Tiene que existir</para>
''' <para> -> No puede ser un fichero oculto                    [FileAttributes.Hidden]</para>
''' <para> -> No puede ser un fichero del sistema               [FileAttributes.System]</para>
''' <para> -> No puede ser un fichero comprimido por el sistema [FileAttributes.Compressed]</para>
''' <para> ** Fichero de salida Comprimido** </para>
''' <para> -> El nombre del fichero tiene que tener una extension, si no la tiene se añade la extension ['.gz']</para>
''' <para> -> No tiene que existir</para>
''' <para> -> PERO si existe solo se sobrecribe  si </para>
''' <para> - El parametro sobreescribirFicheroSalida  tiene el valor true</para>
''' <para>     y ADEMAS</para>
''' <para> - No tiene que ser un fichero oculto                    [FileAttributes.Hidden]</para>
''' <para> - No tiene que ser un fichero de de solo lectura        [FileAttributes.ReadOnly] </para>
''' <para> - No tiene que ser un archivo de sistema                [FileAttributes.System]</para>
''' <para> - No tiene que ser un archivo Comprimido por el sistema [FileAttributes.Compressed]</para>
''' <code>
''' <para> Joaquin Medina Serrano</para>
''' <para> 2011-10-01</para>
''' </code>
''' <code>
''' <para>  gzip: http://es.wikipedia.org/wiki/Gzip  </para>
''' <para> 7-Zip: http://es.wikipedia.org/wiki/7-Zip </para>
''' <para>    7z: http://es.wikipedia.org/wiki/7z    </para>
''' </code>
'''</remarks>
Public Overloads Shared Function ComprimirFichero( _
                      ByVal ficheroEntradaNormal As FileInfo, _
                      ByVal ficheroSalidaComprimido As FileInfo) _
                  As Boolean


    '-------------------------------------
    ' valor de salida (True), se realizo la compresion, 
    ' (False), el proceso ha fallado y no se ha comprimido
        el fichero
    Dim comprimido As Boolean ' = False

    '-------------------------------------
    ' Control de parametros de entrada
    '-------------------------------------
    ' no se realiza en este ejemplo
    '------------------

    '-------------------------------------
    ' Proceso de compresion
    '-------------------------------------
    '--------------------------------------------------------
    ' Obtener la secuencia del archivo de origen.
    Using FSficheroEntrada As FileStream = ficheroEntradaNormal.OpenRead()
        ' Crear el archivo comprimido.
        Using FSficheroSalida As FileStream = ficheroSalidaComprimido.OpenWrite
            Using objCompresor As GZipStream = New GZipStream(FSficheroSalida, CompressionMode.Compress)
                ' Copia el archivo de origen en la secuencia de compresión.
                FSficheroEntrada.CopyTo(objCompresor)
                comprimido = True '--------------------------->>>>>
                '----------------------------------------------
                ' cambiar el atributo a ReadOnly
                ficheroSalidaComprimido.Refresh()
                ' Variable auxiliar que se usa en el proceso de busqueda
                    de atributos
                ' para saber si el fichero tiene o no algun atributo determinado
                Dim auxExisteAtributo As Boolean ' = False
                auxExisteAtributo = ((ficheroSalidaComprimido.Attributes And FileAttributes.ReadOnly) = FileAttributes.ReadOnly)
                If auxExisteAtributo = False Then
                    ficheroSalidaComprimido.Attributes = ficheroSalidaComprimido.Attributes Or FileAttributes.ReadOnly
                End If
                '----------------------------------------------
            End Using
        End Using
    End Using
    Return comprimido
End Function



''' <summary>
''' Funcion que descomprime un fichero ZIP 
''' </summary>
''' <param name="ficheroEntradaComprimido">
''' <para>Tipo <see cref="FileInfo">FileInfo</see></para>
''' <para>El fichero que se quiere descomprimir</para>
'''</param>
''' <param name="ficheroSalidaDescomprimido">
''' <para>Tipo <see cref="FileInfo">FileInfo</see></para>
''' <para>El fichero donde se guardará el fichero descomprimido</para>
''' </param>
''' <returns>
''' <para>Tipo <see cref="Boolean">Boolean</see></para>
''' <para>La operacion de descompresion ha tenido exito (true), o ha fallado (false). </para>
''' <para> TRUE : Si el porceso de descompresion fue satisfactorio</para>
''' <para> FALSE: Si el porceso de descompresion falla. 
''' </para>
''' </returns>
''' <remarks>
''' <para> ** Fichero de Entrada Comprimido ** </para>
''' <para> -> Tiene que existir</para>
''' <para> -> No puede ser un fichero oculto                    [FileAttributes.Hidden]    </para>
''' <para> -> No puede ser un fichero del sistema               [FileAttributes.System]    </para>
''' <para> -> No puede ser un fichero comprimido por el sistema [FileAttributes.Compresed] </para>
''' 
''' <para> ** Fichero de salida Descomprimido** </para>
''' <para> -> No tiene que existir</para>
''' <para> -> PERO si existe solo se sobrecribe si </para>
''' <para> - El parametro sobreescribirFicheroSalida tiene el valor true</para>
''' <para> y ADEMAS</para>
''' <para> - No tiene que ser un fichero oculto                    [FileAttributes.Hidden]     </para>
''' <para> - No tiene que ser un fichero de de solo lectura        [FileAttributes.ReadOnly]   </para>
''' <para> - No tiene que ser un archivo de sistema                [FileAttributes.System]     </para>
''' <para> - No tiene que ser un archivo Comprimido por el sistema [FileAttributes.Compressed] </para>
''' <code>
''' <para> Joaquin Medina Serrano</para>
''' <para> 2011-10-01</para>
''' </code>
''' </remarks>
Public Overloads Shared Function DescomprimirFichero( _
                              ByVal ficheroEntradaComprimido As FileInfo, _
                              ByVal ficheroSalidaDescomprimido As FileInfo) _
                            As Boolean

    '-------------------------------------
    Dim descomprimido As Boolean ' = False

    '-------------------------------------
    ' Control de parametros de entrada
    '-------------------------------------
    ' no se realiza en este ejemplo
    '------------------
    '-------------------------------------
    ' Proceso de descompresion
    '-------------------------------------
    Using FSficheroEntrada As FileStream = ficheroEntradaComprimido.OpenRead
        Using FSficheroSalida As FileStream = ficheroSalidaDescomprimido.Create
            Using zip As GZipStream = New GZipStream(FSficheroEntrada, CompressionMode.Decompress)
                zip.CopyTo(FSficheroSalida)
                descomprimido = True
            End Using
        End Using
    End Using
    Return descomprimido
End Function

↑↑↑

A.2.Enlaces

[Para saber mas]
[Grupo de documentos]
[Documento Index]
[Documento Start]
[Imprimir el Documento]
© 1997 - - La Güeb de Joaquín
Joaquín Medina Serrano
Ésta página es española

Codificación
Fecha de creación
Última actualización
[HTML5 Desarrollado con CSS3 / usando CSS3 y Semantica]