Geral

Compactando e Descompactando arquivos em ASP.NET

Ola Pessoal,

Bom poucos sabem mas o próprio .NET Framework possui classes para efetuar compactação e descompactação de arquivos.
Para isso usaremos a classe GZipStream, que representa o formata de dados o GZip, o qual utiliza algoritmo padrão de compactação da indústria. Para que quiser acessar mais informações sobre o padão GZip acesse http://www.ietf.org/rfc/rfc1951.txt?number=1951 .

Temos que ter atenção a dois detalhes:

  1. A classe GZipStream, não pode ser usada para compactar arquivos maiores que 4 GB.
  2. A funcionalidade de compactação desta classe é efetuada com a leitura de byte-a-byte, portanto sendo melhor usada em fontes não compactadas. Sendo assim se você utilizar esta classe para compactar arquivos já compactados corre-se o risco de aumentar o tamanho do mesmo.

Para exemplificar  criei duas funções, uma para compactação(CompactarArquivo) e outra para descompactação(DescompactarArquivo). Funções que poderam ser invocadas a qualquer momento.As mesmas estão devidamente comentadas.

Antes de codificar as funções devemos importar os seguintes Namespaces:

using System.IO;
using System.IO.Compression;

Agora é só codificar as funções abaixo:

 private void CompactarArquivo(string ArquivoOrigem, string ArquivoDestino)
{
    //Cria uma entrada stream do arquivo de origem para compactação
    FileStream Origem = new FileStream(ArquivoOrigem, FileMode.Open, FileAccess.Read);

    //Cria a saida do arquivo stream, sendo criado um arquivo “.gz”, por exemplo
    FileStream Destino = new FileStream(ArquivoDestino, FileMode.Create, FileAccess.Write);

    //Os bytes serão processados por um compressor de streams(GZipStream)
    GZipStream Compactado = new GZipStream(Destino, CompressionMode.Compress, true);

    //efetua a leitura dos bytes de um arquivo para o outro.
    const int tamanhoBloco = 4096;
    byte[] buffer = new byte[tamanhoBloco];
    int bytesLidos;

    do
    {
        bytesLidos = Origem.Read(buffer, 0, tamanhoBloco);

        if ((bytesLidos == 0))
            break;

        Compactado.Write(buffer, 0, bytesLidos);
    }
    while (true);

    //Fecha todos os streams
    Origem.Close();
    Compactado.Close();
    Destino.Close();
}

private void DescompactarArquivo(string ArquivoOrigem, string ArquivoDestino)
{
    //Cria uma entrada stream do arquivo de origem para descompactação
    FileStream Origem = new FileStream(ArquivoOrigem,FileMode.Open,FileAccess.Read);

    //Cria a saida do arquivo stream, aqui é o arquivo de destino
    FileStream Destino = new FileStream(ArquivoDestino,FileMode.Create,FileAccess.Write);

    //Os bytes serão processados através de um decompressor de stream(GZipStream)
    GZipStream Descompactado = new GZipStream(Origem,CompressionMode.Decompress,true);

    //efetua a leitura dos bytes de um arquivo para o outro.
    const int tamanhoBloco = 4096;
    byte[] buffer = new byte[tamanhoBloco];
    int bytesLidos;
    do
    {
        bytesLidos = Descompactado.Read(buffer, 0, tamanhoBloco);

        if ((bytesLidos == 0))
            break;

        Destino.Write(buffer, 0, bytesLidos);
    }
    while (true);

    //Fecha todos os streams
    Origem.Close();
    Descompactado.Close();
    Destino.Close();
}
 
Só para não esquecer… A classe GZipStream está disponível à partir do .NET Framework 2.0.
Pessoal agora é só usar!
Deixem seus comentários.
[]’s


Bookmark and Share

2 Comments

  1. Ao utilizar seu código de descompactação ocorre a exceção abaixo.

    O número mágico no cabeçalho GZip não está correto. Verifique se você está transmitindo um fluxo GZip

    Obrigado.

Deixe uma resposta