Compactar diretório [RESOLVIDO]

Boa tarde…
Gostaria de saber se tem como compacatar um diretório com a api java.util.zip do java… como fazer…
Os arquivos eu consegui, mas os diretórios não…
Alguém já fez isso…?

Obrigado

Eu uso assim:

public void zipFiles(String dirImp, String dirTmp, String[] filenames, String outFilename) {
	        // Create a buffer for reading the files
	        byte[] buf = new byte[1024];
	        try {
	            // Create the ZIP file
	            ZipOutputStream out = new ZipOutputStream(new FileOutputStream(dirTmp + "/" + outFilename));
	            // Compress the files
	            for (int i = 0; i < filenames.length; i++) {
	                FileInputStream in = new FileInputStream(dirImp + "/" + filenames[i]);
	                // Add ZIP entry to output stream.
	                out.putNextEntry(new ZipEntry(filenames[i]));
	                // Transfer bytes from the file to the ZIP file
	                int len;
	                while ((len = in.read(buf)) > 0) {
	                    out.write(buf, 0, len);
	                }
	                // Complete the entry
	                out.closeEntry();
	                in.close();
	            }
	            // Complete the ZIP file
	            out.close();
	        } catch (IOException e) {
	        }
	    }
	

Testei aqui e funcionou, mas para a ocasião de quando existir um diretório e vários arquivos…
Mas quando existir um diretório dentro de outro…como devo fazer ? Pois a função dá erro quando existir um diretório dentro de outro ou uma árvore completa

Obrigado

Ae Pedrosa…seguindo a sua idéia fiz dois métodos que resolveram meu problema usando recursão…o seu método tbm dá pra fazer isso,
Mas implementei segundo minha linha de pensamento não prescisando informar se é diretório ou arquivo…se alguém prescisar está aí…

 /**
     * Zipa o arquivo ou diretório
     * @param endEntrada endereço do arquivo ou diretório a ser zipado
     * @param endSaida endereço de saída do arquivo zip gerado
     * @return true se zipou certou ou false se deu erro
     */
    public boolean zipar(String endEntrada, String endSaida ) {


        String dirInterno = "";
        boolean retorno = true;


        try {
            File file = new File(endEntrada);

            //Verifica se o arquivo ou diretório existe
            if (!file.exists()) {
                mensagem = ResourceBundle.getMensagem("msg.erro.zip-001");
                return false;

            }

            ZipOutputStream zipDestino = new ZipOutputStream(new FileOutputStream(endSaida));


            //se é um arquivo a ser zipado
            //zipa e retorna
            if (file.isFile()) {
                ziparFile(file, dirInterno, zipDestino);


            } //senão lista o que tem no diretório e zipa
            else {
                dirInterno = file.getName();

                //Verifica se é diretório ou

                File[] files = file.listFiles();



                for (int i = 0; i < files.length; i++) {

                    ziparFile(files[i], dirInterno, zipDestino);

                }
            }
            zipDestino.close();

        } catch (IOException ex) {
            log.error(ResourceBundle.getMensagem("msg.erro.zip-002"), ex);
            mensagem = ResourceBundle.getMensagem("msg.erro.zip-002");
            retorno = false;

        }

        return retorno;

    }


    /**
     * Zipa o arquivo ou diretório passado Verifica se é diretório executa recursão para adicionar os arquivos
     * contidos dentro do mesmo no zip senão somente adiciona o arquivo no zip criado
     * @param file arquivo ou diretório a ser adicionado no zip
     * @param dirInterno diretório interno do zip
     * @param zipDestino zip em que está sendo adicionado os arquivos e diretórios
     * @throws java.io.IOException exeção que pode ser gerada na adição de arquivos no zip
     */
    private void ziparFile(File file, String dirInterno, ZipOutputStream zipDestino) throws IOException {

        byte data[] = new byte[TAM_BUFFER];

        //Verifica se a file é um diretório, então faz a recursão
        if (file.isDirectory()) {


            File[] files = file.listFiles();



            for (int i = 0; i < files.length; i++) {

                ziparFile(files[i], dirInterno + File.separator + file.getName(), zipDestino);

            }


            return;

        }



        FileInputStream fi = new FileInputStream(file.getAbsolutePath());
        ZipEntry entry = new ZipEntry(dirInterno + File.separator + file.getName());
        zipDestino.putNextEntry(entry);
        int count;
        while ((count = fi.read(data)) > 0) {
            zipDestino.write(data, 0, count);
        }
        zipDestino.closeEntry();
        fi.close();

    }

[quote=leopoldof]Ae Pedrosa…seguindo a sua idéia fiz dois métodos que resolveram meu problema usando recursão…o seu método tbm dá pra fazer isso,
Mas implementei segundo minha linha de pensamento não prescisando informar se é diretório ou arquivo…se alguém prescisar está aí…

[code]
/**
* Zipa o arquivo ou diretório
* @param endEntrada endereço do arquivo ou diretório a ser zipado
* @param endSaida endereço de saída do arquivo zip gerado
* @return true se zipou certou ou false se deu erro
*/
public boolean zipar(String endEntrada, String endSaida ) {

    String dirInterno = "";
    boolean retorno = true;


    try {
        File file = new File(endEntrada);

        //Verifica se o arquivo ou diretório existe
        if (!file.exists()) {
            mensagem = ResourceBundle.getMensagem("msg.erro.zip-001");
            return false;

        }

        ZipOutputStream zipDestino = new ZipOutputStream(new FileOutputStream(endSaida));


        //se é um arquivo a ser zipado
        //zipa e retorna
        if (file.isFile()) {
            ziparFile(file, dirInterno, zipDestino);


        } //senão lista o que tem no diretório e zipa
        else {
            dirInterno = file.getName();

            //Verifica se é diretório ou

            File[] files = file.listFiles();



            for (int i = 0; i < files.length; i++) {

                ziparFile(files[i], dirInterno, zipDestino);

            }
        }
        zipDestino.close();

    } catch (IOException ex) {
        log.error(ResourceBundle.getMensagem("msg.erro.zip-002"), ex);
        mensagem = ResourceBundle.getMensagem("msg.erro.zip-002");
        retorno = false;

    }

    return retorno;

}


/**
 * Zipa o arquivo ou diretório passado Verifica se é diretório executa recursão para adicionar os arquivos
 * contidos dentro do mesmo no zip senão somente adiciona o arquivo no zip criado
 * @param file arquivo ou diretório a ser adicionado no zip
 * @param dirInterno diretório interno do zip
 * @param zipDestino zip em que está sendo adicionado os arquivos e diretórios
 * @throws java.io.IOException exeção que pode ser gerada na adição de arquivos no zip
 */
private void ziparFile(File file, String dirInterno, ZipOutputStream zipDestino) throws IOException {

    byte data[] = new byte[TAM_BUFFER];

    //Verifica se a file é um diretório, então faz a recursão
    if (file.isDirectory()) {


        File[] files = file.listFiles();



        for (int i = 0; i < files.length; i++) {

            ziparFile(files[i], dirInterno + File.separator + file.getName(), zipDestino);

        }


        return;

    }



    FileInputStream fi = new FileInputStream(file.getAbsolutePath());
    ZipEntry entry = new ZipEntry(dirInterno + File.separator + file.getName());
    zipDestino.putNextEntry(entry);
    int count;
    while ((count = fi.read(data)) > 0) {
        zipDestino.write(data, 0, count);
    }
    zipDestino.closeEntry();
    fi.close();

}

[/code][/quote]

Olá,
por que que você passa File, String e ZipOutputStream de parâmetro? Você diz que o método está preparado para compactar arquivo ou diretório, não?