他の人が述べたように、コンテンツを既存の zip (または war) に追加することはできません。ただし、抽出されたコンテンツを一時的にディスクに書き込むことなく、その場で新しい zip を作成することは可能です。これがどれほど高速になるかを推測するのは難しいですが、(少なくとも私の知る限りでは) 標準の Java で実現できる最速のものです。Carlos Tasada が述べたように、SevenZipJBindings は余分な秒数を圧迫する可能性がありますが、このアプローチを SevenZipJBindings に移植すると、同じライブラリで一時ファイルを使用するよりも高速になります。
既存の zip (war.zip) の内容を書き込み、追加ファイル (answer.txt) を新しい zip (append.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();
}
}