如何在Java中向现有zip文件添加条目?

可能重复:
使用Java将文件附加到zip文件

使用ZipOutputStream打开文件会覆盖它。 有没有办法保留文件,只是添加新条目?

该函数将现有zip文件重命名为临时文件,然后将现有zip中的所有条目与新文件一起添加,不包括与其中一个新文件同名的zip条目。

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(); } 

您可以使用zipFile.entries()来获取现有文件中所有ZipEntry对象的枚举,循环遍历它们并将它们全部添加到ZipOutputStream,然后另外添加新条目。

以下是JavaWorld关于修改zip存档的详细文章 。

您必须确保为添加到zip中的未压缩文件添加CRC32。 看看这里的例子。 http://jcsnippets.atspace.com/java/input-output/create-zip-file.html


您可以使用Zip4j以简单的方式完成此操作,而无需重写所有内容。 这里显示: http : //blog.michalszalkowski.com/java/zip4j-add-file-to-existing-zip-file/

你也可以使用Zip4J的ZipOutputStream,一起使用SplitOutputStream。

  net.lingala.zip4j zip4j 1.3.1  

例如:

 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);