Como listar o conteúdo de arquivos ZIP ou JAR com uma aplicação Java?
O formato ZIP, atualmente muito popular para o empacotamento e distribuição de software, é o mesmo utilizado pelos arquivos JAR (java archive). A classe java.util.zip.ZipFile permite a criação de um objeto que representa um arquivo ZIP possibilitando determinar o seu conteúdo, isto é, os arquivos existentes neste ZIP (ou JAR) sendo também possível a extração de um ou mais dos arquivos empacotados.
Para criar um objeto ZipFile referente a um arquivo basta fazer:
zip = new ZipFile(nomeArquivoZip);
Para obter-se as entradas existentes neste arquivo e processá-las:
Enumeration entries = zip.entries(); while (entries.hasMoreElements()) { // aqui processamos as entradas : }
Cada entrada é um objeto da classe java.util.zip.ZipEntry que permite obter diversas informações sobre cada arquivo, tais como o tamanho do arquivo, o tamanho comprimido, o CRC ou método utilizado para compressão.
O exemplo abaixo permite todas listar as entradas existentes num arquivo ZIP e, opcionalmente, extrair um destes arquivos.
import java.io.*; import java.util.Enumeration; import java.util.zip.*; public class ZipTool { public static final void main(String args[]) { boolean extractFile = false; int argIndex = 0; ZipFile zip = null; // Valida argumentos if (args.length==0) { usage(); } else if (args[0].equals("-x")) { if (args.length>2) { extractFile = true; argIndex++; } else { usage(); } } // Abre ZipFile try { zip = new ZipFile(args[argIndex]); } catch (ZipException e1) { System.out.println("Exception:\n" + e1.toString()); } catch (IOException e2) { System.out.println("Exception:\n" + e2.toString()); } // Obtem relacao de entradas do arquivo Enumeration entries = zip.entries(); String dir = ""; while (entries.hasMoreElements()) { ZipEntry ze = (ZipEntry)entries.nextElement(); if (ze.isDirectory()) { dir = ze.getName(); continue; } else if (extractFile) { if (ze.getName().equals(args[argIndex+1])) { // Extrai arquivo indicado try { extract(zip, ze); } catch (IOException e) { System.out.println("Can't extract " + ze.getName() + ":\n" + e); } } } else { System.out.println(dir + ze.getName() + " [size:" + ze.getSize() + ", comp:" + ze.getCompressedSize() + "]"); } } } public static void usage() { System.out.println("Usage:\nZipTool [-x] zipfile file"); System.exit(1); } public static void extract(ZipFile zf, ZipEntry ze) throws IOException { System.out.println("Extracting " + ze.getName()); // Criando streams BufferedInputStream zipInput = new BufferedInputStream(zf.getInputStream(ze)); BufferedOutputStream fileOutput = new BufferedOutputStream(new FileOutputStream(ze.getName())); // Obtendo tamanho do arquivo int sz = (int)ze.getSize(); // Extracao do arquivo final int N = 1024; byte buf[] = new byte[N]; int ln = 0; while (sz > 0 && // necessario devido bug JDK1.1 e 1.2 (ln = zipInput.read(buf, 0, Math.min(N, sz))) != -1) { fileOutput.write(buf, 0, ln); sz -= ln; } // Fechando streams zipInput.close(); fileOutput.flush(); fileOutput.close(); } }
Com algumas modificações neste exemplo é possível adicionar-se novos arquivos ao arquivo compactado ZIP ou outras funcionalidades.