Trabalhando com Gzipstream e Deflatestream no C#.NET
Autor: Dalton Dias | Publicado: 2011-09-10T12:32:00-07:00

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.&nbsp;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:


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

/
/* comprimirGzip */

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

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
/* descomprimirGzip */

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

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

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }

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

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

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inFile.CopyTo(Compress);


&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }

/*&nbsp;descomprimirDeflate&nbsp;*/

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; using (FileStream inFile = fi.OpenRead())
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {

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

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

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Decompress.CopyTo(outFile);

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }


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