Trabalhando com Gzipstream e Deflatestream no C#.NET



Sumário


0 - Introdução
1 - O que é GZip?
2 - O que é Deflate?
3 - Exemplo Gzipstream e Deflatestream
4 - Conclusão
5 - Referências


0 - Introdução


Por meio pequeno artigo ou tutorial vou tentar ensinar como fazer para comprimir e descomprimir arquivos utilizando dois algoritmos que a linguagem C#.NET disponiliza para o desenvolvedor. Para desenvolver foi usado o Visual Studio 2008 C#.NET Express (disponilizado gratuitamente no site da Microsoft).




Primeiro vamos enteder o que é o Gzipstream e Deflatestream. Depois vamos botar a mão na massa e desenvolver um pequeno e simples exemplo para cada.



1 - O que é Gzip?


Gzip é um formato inclui um verificação de redundância cíclica valor para detectar corrupção de dados.Atualmente usa o método de compressão deflate mas pode ser facilmente estendido para usar outros métodos de compressão. O formato pode ser implementado rapidamente em uma forma não cobertos por patentes.[1]





2 - O que é Deflate?


Deflate definie um formato de compressão sem perda de dados, usando uma combinação do algoritmo LZ77 e codificação de Huffman, com eficiência comparável aos melhores métodos disponíveis atualmente de compressão de propósito geral.[2]



A funcionalidade de compactação em DeflateStream e GZipStream são expostas como um stream. Os dados são lidos em uma base byte-by-byte, por isso não é possível realizar várias passagens para determinar o melhor método para compressão de arquivos inteiros ou grandes blocos de dados. As classes DeflateStream[3] e GZipStream[4] são mais utilizados em fontes de dados sem compressão. Se os dados de origem já estiver compactada, usando essas classes podem realmente aumentar o tamanho do fluxo.



3 - Exemplo Gzipstream e Deflatestream



Agora vamos para parte prática. Sera mostrado um algoritmo explicando como comprimir e descomprimir em Gzipstream e depois o Deflatestream. Cada um terá um método, totalizando quatro:

  • comprimirGzip;
  • descomprimirGzip;
  • comprimirDeflate;
  • descomprimirDeflate;

Se você é iniciante na linguagem e ainda está aprendendo sobre a sua sintaxe é bom você dar uma lida nessa observação:
using - Você pode entende-lo como a liberação de recursos, logo que ele é chamando o dispose automaticamente. Para saber mais sobre o que é dispose clique aqui.


Todos os métodos recebem como parâmetro um arquivo FileInfo. Ex:




Código:
        public void comprimirGzip(FileInfo fiArq)
        {
             //TODO O MÉTODO AQUI!
        }
ou
Código:
        public void comprimirGzip(FileInfo fi)


        {
             //TODO O MÉTODO AQUI!
        }




/* comprimirGzip */




Código:
                // Cria uma stream,
                // nela fica contido o conteudo no arquivo.
                using (FileStream inFile = fiArq.OpenRead())
                {
                    // Pega o Nome inteiro do arquivo
                    // Verifica se o nome do arquivo eh diferente de .gz
                    // EX: arquivo.exe.gz fica arquivo.exe
                    if ((File.GetAttributes(fiArq.FullName)
                        & FileAttributes.Hidden)
                        != FileAttributes.Hidden & fiArq.Extension != ".gz")
                    {
                        // Cria um arquivo .gz
                        // Recebera o conteudo do arquivo original
                        // para depois ser comprimido.
                        using (FileStream outFile =
                                    File.Create(fiArq.FullName + ".gz"))
                        {
                            // Compress cria o arquivo comprimido.
                            using (GZipStream Compress =
                                new GZipStream(outFile,
                                CompressionMode.Compress))
                            {
                                // Copia o conteudo de Compress
                                inFile.CopyTo(Compress);


                             
                            }
                        }
                    }
                }


/* descomprimirGzip */








Código:
                // Cria uma FileStream,
                // nela fica contido o conteudo no arquivo.
                using (FileStream inFile = fi.OpenRead())
                {
                    // Remove a extencao para pegar
                    // somente o nome do arquivo
                    string curFile = fi.FullName;
                    string origName = curFile.Remove(curFile.Length -
                            fi.Extension.Length);


                    // Cria um FileStream semelhante ao metodo de comprimir
                    using (FileStream outFile = File.Create(origName))
                    {
                        using (GZipStream Decompress = new GZipStream(inFile,
                                CompressionMode.Decompress))
                        {
                           
                            Decompress.CopyTo(outFile);


                       


                        }
                    }
                }


Os outros dois métodos para Deflate não fogem dessa estrutura. Não há segredo!


/* comprimirDeflate */




Código:
            using (FileStream inFile = fi.OpenRead())
            {
           
                if ((File.GetAttributes(fi.FullName) & FileAttributes.Hidden)
                    != FileAttributes.Hidden & fi.Extension != ".cmp")
                {
               
                    using (FileStream outFile =
                            File.Create(fi.FullName + ".cmp"))
                    {
                        // A unica coisa que muda é o metodo de compressao!
                        using (DeflateStream Compress =
                            new DeflateStream(outFile,
                            CompressionMode.Compress))
                        {


                            inFile.CopyTo(Compress);




                        }
                    }
                }
            }
/* descomprimirDeflate */




Código:
            using (FileStream inFile = fi.OpenRead())
            {


                string curFile = fi.FullName;
                string origName = curFile.Remove(curFile.Length
                        - fi.Extension.Length);


                 using (FileStream outFile = File.Create(origName))
                {
                    using (DeflateStream Decompress = new DeflateStream(inFile,
                        CompressionMode.Decompress))
                    {


                        Decompress.CopyTo(outFile);


                    }
                }
            }




4 - Conclusão


Foi possível observar neste pequeno tutorial uma forma simples e básica de compressão que você pode usar no dia-a-dia para tarefas simples. O nível de dificuldade para implementar essa solução é básica, foi usada pouca lógica e bastante a classes e métodos que a GZipstream, Deflatestream e a linguagem e plataforma C#.NET fornecem ao desenvolvedor.



5 - Referências


[1] - RFC: 1952 - GZIP file format specification version 4.3. Disponível em: http://www.ietf.org/rfc/rfc1952.txt
[2] - RFC: 1951 - Deflate Compressed Data Format Specification version 1.3. Disponível em: http://www.ietf.org/rfc/rfc1951.txt
[3] - Classe DeflateStream. Disponível em: http://msdn.microsoft.com/pt-br/libr...atestream.aspx
[4] - Classe GzipStream Class. Disponível em: http://msdn.microsoft.com/pt-br/libr...zipstream.aspx