正如其他人提到的,不可能将内容附加到现有的zip(或WAR)中。但是,可以在不将提取的内容临时写入磁盘的情况下动态创建新的zip。很难猜测这会有多快,但这是使用标准Java所能达到的最快速度(至少据我所知)。正如CarlosTasada所提到的,SevenZipJBindings可能会挤出一些额外的时间,但是将这种方法移植到SevenZipJBindings仍然比在同一个库中使用临时文件要快。
下面是一些代码,用于编写现有zip(war.zip)的内容,并将一个额外的文件(responer.txt)附加到一个新zip(附录.zip)中。所需的只是Java 5或更高版本,不需要额外的库。import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;
import java.io.OutputStream;import java.util.Enumeration;import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;import java.util.zip.ZipOutputStream;public class Main {
// 4MB buffer
private static final byte[] BUFFER = new byte[4096 * 1024];
/**
* copy input to output stream - available in several StreamUtils or Streams classes
*/
public static void copy(InputStream input, OutputStream output) throws IOException {
int bytesRead;
while ((bytesRead = input.read(BUFFER))!= -1) {
output.write(BUFFER, 0, bytesRead);
}
}
public static void main(String[] args) throws Exception {
// read war.zip and write to append.zip
ZipFile war = new ZipFile("war.zip");
ZipOutputStream append = new ZipOutputStream(new FileOutputStream("append.zip"));
// first, copy contents from existing war
Enumeration extends ZipEntry> entries = war.entries();
while (entries.hasMoreElements()) {
ZipEntry e = entries.nextElement();
System.out.println("copy: " + e.getName());
append.putNextEntry(e);
if (!e.isDirectory()) {
copy(war.getInputStream(e), append);
}
append.closeEntry();
}
// now append some extra content
ZipEntry e = new ZipEntry("answer.txt");
System.out.println("append: " + e.getName());
append.putNextEntry(e);
append.write("42\n".getBytes());
append.closeEntry();
// close
war.close();
append.close();
}}