Manipulando Arquivos ZIP em Java com ZipOutputStream e ZipInputStream
Java oferece suporte nativo para a criação e leitura de arquivos compactados no formato ZIP através das classes do pacote java.util.zip
. Essa funcionalidade é ideal para arquivar logs, empacotar recursos de uma aplicação ou simplesmente para reduzir o tamanho de arquivos para transferência.
Criando Arquivos ZIP com ZipOutputStream
A classe ZipOutputStream
é um "decorator" que envolve um OutputStream
para escrever dados em formato ZIP. O processo para adicionar arquivos a um arquivo ZIP é o seguinte:
- Para cada arquivo a ser adicionado, cria-se um objeto
ZipEntry
. Ele representa uma entrada (um arquivo ou diretório) dentro do ZIP. - Adiciona-se a entrada ao stream com o método
putNextEntry()
. - Escreve-se o conteúdo do arquivo no
ZipOutputStream
. - Fecha-se a entrada atual com
closeEntry()
para finalizar a escrita do arquivo atual.
O exemplo a seguir demonstra como compactar múltiplos arquivos em um único output.zip
:
import java.io.*;
import java.util.zip.*;
public class CreateZip {
public static void main(String[] args) {
String[] sourceFiles = {"notes.txt", "image.png"}; // Arquivos a serem compactados
String zipFile = "output.zip";
try (ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(zipFile))) {
for (String source : sourceFiles) {
File fileToZip = new File(source);
try (FileInputStream fis = new FileInputStream(fileToZip)) {
// Cria uma entrada no ZIP com o nome do arquivo
ZipEntry zipEntry = new ZipEntry(fileToZip.getName());
zout.putNextEntry(zipEntry);
// Copia os dados do arquivo para o stream ZIP usando um buffer
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
zout.write(buffer, 0, length);
}
}
zout.closeEntry();
}
System.out.println("Arquivo ZIP criado com sucesso.");
} catch (IOException ex) {
System.err.println(ex.getMessage());
}
}
}
Lendo e Extraindo Arquivos ZIP com ZipInputStream
Para ler e extrair o conteúdo de um arquivo ZIP, utiliza-se a ZipInputStream
, que envolve um InputStream
. O método getNextEntry()
é usado para iterar sobre cada entrada (arquivo ou diretório) dentro do ZIP. Ele retorna um ZipEntry
ou null
se não houver mais entradas.
O exemplo a seguir descompacta o output.zip
em um novo diretório chamado extracted
:
import java.io.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.util.zip.*;
public class ExtractZip {
public static void main(String[] args) {
String zipFile = "output.zip";
Path destDir = Paths.get("extracted"); // Diretório de destino
try (ZipInputStream zin = new ZipInputStream(new FileInputStream(zipFile))) {
ZipEntry entry;
while ((entry = zin.getNextEntry()) != null) {
Path filePath = destDir.resolve(entry.getName());
if (entry.isDirectory()) {
// Se for um diretório, cria-o
Files.createDirectories(filePath);
} else {
// Se for um arquivo, garante que o diretório pai exista
Files.createDirectories(filePath.getParent());
// Extrai o arquivo usando um buffer
try (FileOutputStream fout = new FileOutputStream(filePath.toFile())) {
byte[] buffer = new byte[1024];
int length;
while ((length = zin.read(buffer)) > 0) {
fout.write(buffer, 0, length);
}
}
}
zin.closeEntry();
}
System.out.println("Arquivos extraídos com sucesso.");
} catch (IOException ex) {
System.err.println(ex.getMessage());
}
}
}
Este código é robusto: ele verifica se uma entrada é um diretório e o cria. Se for um arquivo, ele garante que a estrutura de diretórios pai exista antes de tentar extraí-lo, permitindo a descompressão correta de arquivos ZIP que contêm pastas.
Resumo
- O pacote
java.util.zip
fornece as classes para manipulação de arquivos ZIP. ZipOutputStream
é usado para criar arquivos ZIP. O processo é: criarZipEntry
, chamarputNextEntry()
, escrever os dados e chamarcloseEntry()
.ZipInputStream
é usado para ler e extrair o conteúdo de arquivos ZIP.- O método
getNextEntry()
permite iterar sobre todas as entradas do arquivo ZIP. - Ao extrair, é importante verificar se uma entrada é um diretório (
isDirectory()
) para recriar a estrutura de pastas corretamente. - A leitura e escrita de dados de e para os streams ZIP deve ser feita com um buffer para garantir eficiência.