¿Cómo puedo agregar entradas a un archivo zip existente en Java?

Posible duplicado:
Anexar archivos a un archivo zip con Java

Abrir el archivo con ZipOutputStream lo sobrescribe. ¿Hay alguna forma de guardar el archivo y solo agregar nuevas entradas?

La función cambia el nombre del archivo zip existente a un archivo temporal y luego agrega todas las entradas en el zip existente junto con los nuevos archivos, excluyendo las entradas zip que tienen el mismo nombre que uno de los archivos nuevos.

public static void addFilesToExistingZip(File zipFile, File[] files) throws IOException { // get a temp file File tempFile = File.createTempFile(zipFile.getName(), null); // delete it, otherwise you cannot rename your existing zip to it. tempFile.delete(); boolean renameOk=zipFile.renameTo(tempFile); if (!renameOk) { throw new RuntimeException("could not rename the file "+zipFile.getAbsolutePath()+" to "+tempFile.getAbsolutePath()); } byte[] buf = new byte[1024]; ZipInputStream zin = new ZipInputStream(new FileInputStream(tempFile)); ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile)); ZipEntry entry = zin.getNextEntry(); while (entry != null) { String name = entry.getName(); boolean notInFiles = true; for (File f : files) { if (f.getName().equals(name)) { notInFiles = false; break; } } if (notInFiles) { // Add ZIP entry to output stream. out.putNextEntry(new ZipEntry(name)); // Transfer bytes from the ZIP file to the output file int len; while ((len = zin.read(buf)) > 0) { out.write(buf, 0, len); } } entry = zin.getNextEntry(); } // Close the streams zin.close(); // Compress the files for (int i = 0; i < files.length; i++) { InputStream in = new FileInputStream(files[i]); // Add ZIP entry to output stream. out.putNextEntry(new ZipEntry(files[i].getName())); // 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(); tempFile.delete(); } 

Puede usar zipFile.entries () para obtener una enumeración de todos los objetos ZipEntry en el archivo existente, recorrerlos y agregarlos a ZipOutputStream, y luego agregar sus nuevas entradas además.

Aquí hay un artículo detallado de JavaWorld sobre la modificación de archivos comprimidos.

Debe asegurarse de agregar un CRC32 para archivos sin comprimir agregados a un archivo comprimido. Mira el ejemplo aquí. http://jcsnippets.atspace.com/java/input-output/create-zip-file.html


Puedes hacerlo de una manera simple, sin reescribir todo, con Zip4j. Aquí se muestra: http://blog.michalszalkowski.com/java/zip4j-add-file-to-existing-zip-file/

Y también puedes hacerlo usando ZipOutputStream de Zip4J, usando SplitOutputStream juntos.

  net.lingala.zip4j zip4j 1.3.1  

ex:

 ZipFile zipFile = new ZipFile(new File("/home/szalek/zip/core1.zip")); ArrayList filesToAdd = new ArrayList(); filesToAdd.add(new File("/home/szalek/zip/someData.txt")); ZipParameters parameters = new ZipParameters(); parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); //password parameters.setEncryptFiles(true); parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD); parameters.setPassword("test123!"); //password zipFile.addFiles(filesToAdd, parameters);