Framework / Api para descompactar arquivos em java

O titulo já e bem explicativo rs.

Alguém sabe algum ?

Dá uma olhada nisso aqui:

Há alguns anos escrevi uma classe ZipUtils com dois métodos públicos: compress e extract.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 * Classe utilitária para compactação e descompactação de arquivos ZIP
 * 
 * @author Ricardo Artur Staroski
 */
public final class ZipUtils {

    /**
     * Compacta determindado arquivo ou diretório para o arquivo ZIP especificado
     * 
     * @param input
     *            O arquivo ou diretório de entrada
     * @param output
     *            O arquivo ZIP de saída
     *
     * @return O checksum da compactação do arquivo
     */
    public static long compress(final File input, final File output) throws IOException {
        if (!input.exists()) {
            throw new IOException(input.getName() + " não existe!");
        }
        if (output.exists()) {
            if (output.isDirectory()) {
                throw new IllegalArgumentException("\"" + output.getAbsolutePath() + "\" não é um arquivo!");
            }
        } else {
            final File parent = output.getParentFile();
            if (parent != null) {
                parent.mkdirs();
            }
            output.createNewFile();
        }
        Checksum checksum = createChecksum();
        final ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(output));
        zip.setLevel(Deflater.BEST_COMPRESSION);
        compressInternal(null, input, zip, checksum);
        zip.finish();
        zip.flush();
        zip.close();
        return checksum.getValue();
    }

    /**
     * Extrai um arquivo ZIP para o diretório especificado
     * 
     * @param input
     *            O arquivo ZIP de entrada
     * @param output
     *            O diretório de saída
     * @return O checksum da descompactação do arquivo
     */
    public static long extract(final File input, final File output) throws IOException {
        if (input.exists()) {
            if (input.isDirectory()) {
                throw new IllegalArgumentException("\"" + input.getAbsolutePath() + "\" não é um arquivo!");
            }
        } else {
            throw new IllegalArgumentException("\"" + input.getAbsolutePath() + "\" não existe!");
        }
        if (output.exists()) {
            if (output.isFile()) {
                throw new IllegalArgumentException("\"" + output.getAbsolutePath() + "\" não é um diretório!");
            }
        }
        Checksum checksum = createChecksum();
        final ZipInputStream zip = new ZipInputStream(new FileInputStream(input));
        extractInternal(zip, output, checksum);
        zip.close();
        return checksum.getValue();
    }

    // Adiciona determinado arquivo ao ZIP
    private static void compressInternal(final String caminho, final File arquivo, final ZipOutputStream zip, Checksum checksum) throws IOException {
        final boolean dir = arquivo.isDirectory();
        String nome = arquivo.getName();
        nome = (caminho != null ? caminho + "/" + nome : nome);
        final ZipEntry item = new ZipEntry(nome + (dir ? "/" : ""));
        item.setTime(arquivo.lastModified());
        zip.putNextEntry(item);
        if (dir) {
            zip.closeEntry();
            final File[] arquivos = arquivo.listFiles();
            for (int i = 0; i < arquivos.length; i++) {
                // recursivamente adiciona outro arquivo ao ZIP
                compressInternal(nome, arquivos[i], zip, checksum);
            }
        } else {
            item.setSize(arquivo.length());
            final FileInputStream entrada = new FileInputStream(arquivo);
            copy(entrada, zip, checksum);
            entrada.close();
            zip.closeEntry();
        }
    }

    /**
     * Copia o conte&uacute;do do stream de entrada para o stream de sa&iacute;da.
     * 
     * @param from
     *            O stream de entrada.
     * @param to
     *            O stream de sa&iacute;da.
     * @param checksum
     *            O checksum da escrita.
     * @throws IOException
     */
    private static void copy(InputStream from, OutputStream to, Checksum checksum) throws IOException {
        byte[] bytes = new byte[8192];
        for (int read = -1; (read = from.read(bytes)) != -1; to.write(bytes, 0, read)) {
            checksum.update(bytes, 0, read);
        }
        to.flush();
    }

    private static Checksum createChecksum() {
        return new CRC32();
    }

    // Retira determinado elemento do arquivo ZIP
    private static void extractInternal(final ZipInputStream zip, final File pasta, Checksum checksum) throws IOException {
        ZipEntry elemento = null;
        while ((elemento = zip.getNextEntry()) != null) {
            String nome = elemento.getName();
            nome = nome.replace('/', File.separatorChar);
            nome = nome.replace('\\', File.separatorChar);
            File arquivo = new File(pasta, nome);
            if (elemento.isDirectory()) {
                arquivo.mkdirs();
            } else {
                boolean existe = arquivo.exists();
                if (!existe) {
                    final File parent = arquivo.getParentFile();
                    if (parent != null) {
                        parent.mkdirs();
                    }
                    arquivo.createNewFile();
                }
                boolean oculto = false;
                boolean somenteLeitura = false;
                if (existe) {
                    oculto = arquivo.isHidden();
                    if (oculto) {
                        Files.setAttribute(arquivo.toPath(), "dos:hidden", false);
                    }
                    somenteLeitura = !arquivo.canWrite();
                    if (somenteLeitura) {
                        arquivo.setWritable(true);
                    }
                }

                OutputStream saida = new FileOutputStream(arquivo);
                copy(zip, saida, checksum);
                saida.close();

                if (existe) {
                    if (somenteLeitura) {
                        arquivo.setWritable(false);
                    }
                    if (oculto) {
                        Files.setAttribute(arquivo.toPath(), "dos:hidden", true);
                    }
                }
            }
            arquivo.setLastModified(elemento.getTime());
        }
    }

    // Construtor privado - Náo há razão em instanciar esta classe
    private ZipUtils() {}
}

Não resolveu pois o método copy não está feito

Eu havia postado o link do fonte no GitHub, lá o método copy está implementado em outra classe, era só copiar aquela classe, ou implementar o método, afinal, não há mistério em copiar o conteúdo de um InputStream para um OutputStream. :wink:

Todavia alterei o fonte e postei novamente, agora o copy está na própria classe ZipUtils.
:slight_smile: