Trabalhando com arquivos ZIP em C# (.NET): guia completo
No desenvolvimento moderno na plataforma .NET, trabalhar com arquivos é uma das tarefas comuns. Seja para empacotar logs, descompactar configurações ou criar backups, os recursos integrados do System.IO.Compression permitem fazer isso de forma eficiente e sem bibliotecas de terceiros. Neste artigo, abordaremos as principais operações com arquivos ZIP em C#, incluindo compressão, extração, adição de arquivos e trabalho com streams.
Namespaces necessários
Para trabalhar com arquivos no .NET, são usados dois namespaces principais:
using System.IO;using System.IO.Compression;A partir do .NET Framework 4.5, a classe ZipFile está disponível no assembly System.IO.Compression.FileSystem. No .NET Core / .NET 5+, ela faz parte da biblioteca base.
Criando um arquivo ZIP a partir de arquivos
A maneira mais simples de criar um arquivo é usar o método estático ZipFile.CreateFromDirectory. Ele aceita o caminho da pasta, o caminho do arquivo e o nível de compressão.
string sourceFolder = @"C:\\Temp\\Documents";string zipPath = @"C:\\Temp\\backup.zip";
// Cria o arquivo com compressão OptimalZipFile.CreateFromDirectory(sourceFolder, zipPath, CompressionLevel.Optimal, false);
Console.WriteLine($"Arquivo criado: {zipPath}");Parâmetros:
- sourceFolder — diretório de origem;
- zipPath — caminho para o futuro arquivo;
- CompressionLevel —
Optimal,FastestouNoCompression; - includeBaseDirectory — se
true, a pasta raiz será incluída no arquivo.
Descompactando um arquivo ZIP
A extração de arquivos é feita com o método ZipFile.ExtractToDirectory:
string zipPath = @"C:\\Temp\\backup.zip";string extractPath = @"C:\\Temp\\Restored";
// Descompacta sobrescrevendo arquivos existentesZipFile.ExtractToDirectory(zipPath, extractPath, overwriteFiles: true);
Console.WriteLine("Arquivo descompactado.");No .NET 6+, foi adicionado o parâmetro overwriteFiles, que permite sobrescrever arquivos sem exceções.
Adicionando arquivos a um arquivo existente
A classe ZipArchive oferece controle total sobre o conteúdo. Vamos abrir o arquivo no modo de atualização e adicionar um novo arquivo:
string zipPath = @"C:\\Temp\\backup.zip";string newFile = @"C:\\TempewDocument.txt";
using (FileStream zipStream = new FileStream(zipPath, FileMode.Open, FileAccess.ReadWrite))using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Update)){ // Cria uma entrada no arquivo ZipArchiveEntry entry = archive.CreateEntry("newDocument.txt");
using (StreamWriter writer = new StreamWriter(entry.Open())) { writer.Write("Este é o conteúdo do novo arquivo."); }
Console.WriteLine($"Arquivo {newFile} adicionado ao arquivo.");}Importante: ao usar ZipArchiveMode.Update, o arquivo deve estar aberto para leitura e gravação.
Lendo o conteúdo do arquivo sem descompactar
Às vezes, é necessário apenas visualizar quais arquivos estão dentro. Para isso, iteramos pelas entradas do arquivo:
string zipPath = @"C:\\Temp\\backup.zip";
using (FileStream zipStream = new FileStream(zipPath, FileMode.Open, FileAccess.Read))using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Read)){ foreach (ZipArchiveEntry entry in archive.Entries) { Console.WriteLine($"Arquivo: {entry.FullName}, Tamanho: {entry.Length} bytes"); }}A propriedade FullName contém o caminho dentro do arquivo, incluindo subpastas.
Trabalhando com streams: compressão e descompactação em memória
Para cenários em que o arquivo precisa ser transmitido pela rede ou salvo em um banco de dados, é conveniente usar MemoryStream:<