Para manipular arquivos Zip a primeira coisa que devemos fazer é baixar a biblioteca gratuita SharpZipLib no site: http://www.icsharpcode.net/OpenSource/SharpZipLib/ lá também é possivel encontrar a descrição da licença sob a qual a biblioteca é distribuída.

Adicione uma referencia à DLL da biblioteca no seu projeto.

Vamos aos códigos!

Devemos importar os namespaces:

using ICSharpCode.SharpZipLib.Zip;

using System.IO;

Agora vamos escrever um método para compactar os arquivos:

public void compactar()

        {
            int TAMANHO_STREAM = 4096;

            FileStream objStreamDestino = 
new FileStream("c:\\ArquivoCompactado.zip", FileMode.Create, FileAccess.Write);
//Arquivo que vai ser gerado FileStream arquivo = new FileStream("c:\\arquivo.doc", FileMode.Open, FileAccess.Read);
//Arquivo que será compactado
ZipOutputStream objZipDestino = new ZipOutputStream(objStreamDestino); objZipDestino.Password = "123456";
// Aqui informamos qual será a senha para acesso ao arquivo zip try { byte[] buffer = new byte[TAMANHO_STREAM];
//Criando um array para servir como armazenador durante a iteração sobre o objeto.
ZipEntry entrada = new ZipEntry("arquivo.doc"); /* Criando uma nova entrada de arquivos,
já já entenderemos melhor o que isso significa.
Devemos passar como parâmetro o nome do arquivo que será inserido no .zip,
NÃO devemos colocar o caminho do arquivo que será compactado somente o nome.*/
objZipDestino.PutNextEntry(entrada);
// Aqui adicionamos no arquivo destino à entrada de arquivo que criamos na linha acima.
objZipDestino.Password = "123456";
// Aqui informamos qual será a senha para acesso ao arquivo zip
int bytesLidos = 0; do { bytesLidos = arquivo.Read(buffer, 0, TAMANHO_STREAM);
/* lendo o arquivo a ser compactado,
os bytes lidos são colocados no array buffer e a da quantidade e
bytes lidos é inserida na variável bytesLidos o valor do terceiro
parâmetro deve ser o mesmo que colocamos no tamanho do array buffer*/
objZipDestino.Write(buffer, 0, bytesLidos);/*escrevendo no arquivo zipado,
o buffer contém os dados que devem ser inseridos e a variável bytesLidos
informa ao método quantos bytes contidos no buffer ele deve realmente inserir.
 Tendo em vista que: digamos que só haja 2 bytes no arquivo de origem,
as duas primeiras posições do array buffer seriam preenchidas as outras
 permaneceriam vazias, você não quer que bytes vazios sejam inseridos no seu
.ZIP pois estes podem corrompe-lo, portando é de suma importância saber realmente
quantos bytes são relevantes dentro do array*/
} while (bytesLidos > 0);
// enquanto o número de bytes lidos é maior que zero faz-se o loop /*é importante entender que a informação é lida e escrita em blocos, nesse caso ele Lê 4096 bytes Insere 4096 bytes Lê 4096 bytes Insere 4096 bytes E assim vai até não haver mais bytes a serem lidos. */ } catch (Exception e) { throw e; // Aqui devemos tratar se algum erro ocorrer neste
//caso estou repassando a bucha para o método que chamou.
} finally { //fechando as comunicações. arquivo.Close(); objZipDestino.Close(); objStreamDestino.Close(); } }



Agora um método para descompactar os arquivos:

 

public void descompactar()

        {
            int TAMANHO_STREAM = 4096;

            //arquivo zipado de origem

            FileStream objStreamOrigem = 
new FileStream("c:\\ArquivoCompactado.zip", FileMode.Open, FileAccess.Read); //Cria um novo stream para manipulação do ZIP,
//enviando como parâmetro o zip criado anteriormente
ZipInputStream objZipOrigem = new ZipInputStream(objStreamOrigem); //senha para abrir o arquivo zip objZipOrigem.Password = "123456"; //Criamos aqui a variável de referência que indicará o arquivo descompactado FileStream objStreamDestino = null; //diretório onde irá ser colocado o arquivo descompactado string diretorioDestino = "c:\\descompactados\\"; byte[] buffer = new byte[TAMANHO_STREAM]; int bytesLidos = 0; try { /* podem existir vários arquivos dentro do zip, o GetNextEntry pega o proximo arquivo da lista, a cada vez que
ele for chamado retorna o proximo da fila*/
ZipEntry entrada = objZipOrigem.GetNextEntry(); // criando o Stream para escrever no arquivo descompactado, entrada.
//Name pega o nome do arquivo que está dentro do zip
objStreamDestino =
new FileStream(diretorioDestino + entrada.Name, FileMode.Create, FileAccess.Write); do{ bytesLidos = objZipOrigem.Read(buffer, 0, TAMANHO_STREAM); objStreamDestino.Write(buffer, 0, bytesLidos); } while (bytesLidos > 0); } catch (Exception e) { throw e; } finally { objStreamDestino.Close(); objZipOrigem.Close(); objStreamOrigem.Close(); } }

 

Vale lembrar que a propriedade password pode não ser "setada", nesse caso o ZIP será gerado ou lido sem password.

Os exemplos de código acima são apenas didáticos, dificilmente faremos um programa que compacte somente um arquivo ou retire somente um arquivo de dentro de um zip. Por isso, eu coloquei para download uma classe com os métodos já apresentados neste artigo e mais dois métodos que realizam a compactação de uma lista de arquivos e a descompactação de vários arquivos que estejam dentro do mesmo zip.

Até a próxima ;-)