10 de set de 2011

Trabalhando com Gzipstream e Deflatestream no C#.NET

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:


       
public voidcomprimirGzip(FileInfo fiArq)
{
  //TODO O MÉTODO AQUI!
}
ou    
public void comprimirGzip(FileInfo fi)
{
             //TODO O MÉTODO AQUI!
}


/
/* comprimirGzip */

/ 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 */

// 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 */
            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 */

            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/library/system.io.compression.deflatestream.aspx
[4] - Classe GzipStream Class. Disponível em: http://msdn.microsoft.com/pt-br/library/system.io.compression.gzipstream.aspx

Nenhum comentário:

Postar um comentário