Put files inside a .zip file

3

I have a class where I compile some files:

public class CompactarArquivo {

    //Constante
    static final int TAMANHO_BUFFER = 4096; // 4kb

    //método para compactar arquivo
    public static void compactarParaZip(String arqSaida, String arqEntrada, String arqEntrada1)
            throws IOException {

        FileOutputStream destino;
        ZipOutputStream saida;

        try {
            destino = new FileOutputStream(new File(arqSaida));
            saida = new ZipOutputStream(new BufferedOutputStream(destino));

            add(arqEntrada, saida);
            add(arqEntrada1, saida); 

            saida.close();

        } catch (IOException e) {
            throw new IOException(e.getMessage());
        }
    }

    private static void add(String arquivo, ZipOutputStream saida) throws IOException {
        int cont;
        byte[] dados = new byte[TAMANHO_BUFFER];

        File file = new File(arquivo);
        BufferedInputStream origem = new BufferedInputStream(new FileInputStream(file), TAMANHO_BUFFER);
        ZipEntry entry = new ZipEntry(file.getName());
        saida.putNextEntry(entry);

        while ((cont = origem.read(dados, 0, TAMANHO_BUFFER)) != -1) {
            saida.write(dados, 0, cont);
        }

        origem.close();
    }

In this class I get two files and generate a .zip . But I would like to open this file .zip later and add more files inside it. How do I solve this problem?

    
asked by anonymous 19.10.2015 / 13:33

2 answers

1

If you are using a version prior to Java 7, the best way to do this is to unzip the files inside the .zip and play along with the new files in a new . zip .

Based on on this SOen response .

private static void addFilesToZip(File source, File[] files, String path){
    try{
        File tmpZip = File.createTempFile(source.getName(), null);
        tmpZip.delete();

        if(!source.renameTo(tmpZip)){
            throw new Exception("Não foi possível criar o arquivo temporário (" + source.getName() + ")");
        }

        byte[] buffer = new byte[TAMANHO_BUFFER];
        ZipInputStream zin = new ZipInputStream(new FileInputStream(tmpZip));
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(source));

        for(int i = 0; i < files.length; i++){
            InputStream in = new FileInputStream(files[i]);
            out.putNextEntry(new ZipEntry(path + files[i].getName()));                
            for(int read = in.read(buffer); read > -1; read = in.read(buffer)){
                out.write(buffer, 0, read);
            }                
            out.closeEntry();
            in.close();
        }

        for(ZipEntry ze = zin.getNextEntry(); ze != null; ze = zin.getNextEntry()){
            if(!zipEntryMatch(ze.getName(), files, path)){
                out.putNextEntry(ze);
                for(int read = zin.read(buffer); read > -1; read = zin.read(buffer)){
                    out.write(buffer, 0, read);
                }
                out.closeEntry();
            }
        }
        out.close();
        tmpZip.delete();
    }catch(Exception e){
        e.printStackTrace();
    }
}

private static boolean zipEntryMatch(String zeName, File[] files, String path){
    for(int i = 0; i < files.length; i++){
        if((path + files[i].getName()).equals(zeName)){
            return true;
        }
    }
    return false;
}

This second method checks to see if there is no longer a file with the same name inside Zip . Obviously this needs to be improved, but it is already a good starting point.

If you are using Java 7. You can use the java.nio library and do so (Example removed da

private static void addNoZipExistente(String arqZip, String arqInserir, String nomeArquivoNoZip){       
    Map<String, String> env = new HashMap<>(); 
    env.put("create", "true");

    URI uri = URI.create("jar:" + "file:/" + arqZip.replace("\", "/"));

    try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) 
    {
        Path arquivoParaInserir = Paths.get(arqInserir);
        Path localNoZip = zipfs.getPath(nomeArquivoNoZip);      

        Files.copy(arquivoParaInserir, localNoZip, StandardCopyOption.REPLACE_EXISTING ); 
    }catch(IOException ioex){
        //Tratar o erro
    }
}

Otherwise, I would also change the way you receive the parameters in the compactarParaZip() method so that it can receive multiple parameters. Maybe you only need two, but that makes the method more dynamic.

public static void compactarParaZip(String arqSaida, String... entradas) throws IOException {

    FileOutputStream destino;
    ZipOutputStream saida;

    try {
        destino = new FileOutputStream(new File(arqSaida));
        saida = new ZipOutputStream(new BufferedOutputStream(destino));

        for(String arq : entradas){
            add(arq, saida);
        }

        saida.close();

    } catch (IOException e) {
        throw new IOException(e.getMessage());
    }
}

An example of how to use it would be

compactarParaZip("novoArquivo.zip", "arq1.txt", "arq2.txt", "arq3.txt");
// posso colocar quantos parâmetros quiser
    
19.10.2015 / 16:51
3

I found a tutorial in English and did the translation and testing it. To insert files within a ZIP file you must use the NIO library, present in Java 7 or higher.

    Map<String, String> zip_properties = new HashMap<>();

    /* Se o arquivo ZIP já existe, coloque false*/
    zip_properties.put("create", "false");

    zip_properties.put("encoding", "UTF-8");

    Path path = Paths.get("C:\Temp\Arquivos.zip");

    /* Especifique o caminho para o arquivo zip que você quer ler como um sistema de arquivos */
    URI zip_disk = URI.create("jar:" + path.toUri());

     /* Cria o Sistema de arquivo ZIP */
    try (FileSystem zipfs = FileSystems.newFileSystem(zip_disk, zip_properties)) {

        /* Cria o arquivo dentro do ZIP*/
        Path ZipFilePath = zipfs.getPath("footer.html");

        /* Caminho do arquivo que deve ser adicionado */
        Path addNewFile = Paths.get("C:\Temp\footer.html");

        Files.copy(addNewFile, ZipFilePath);
    }

Before running the code

Afterthecodeisexecuted

The.htmlfileIplacedinsidethezipwasnotcorrupted.

Source: link

    
19.10.2015 / 14:45