As far as I can see How to split a huge zip file into multiple volumes? just suggests keeping track of the archive size so far, and when it approaches some arbitrary value (which should be lower than your max), it'll decide to start a new file. So for a 16MB limit, you could set the value to 10MB and start a new zip whenever this is reached, but if you reach 9MB and your next file zips down to 8MB, you'll end up with a zip bigger than your limit.
The code given in that post didn't seem to work for me because 1) it got the size before the ZipEntry was created, so it was always 0 and 2) it didn't write out any zip :-) If I've got that wrong - let me know.
The following works for me. For simplicity, I've taken it out of the Wrapper and just have it all in main(String args[]). There are many, many ways this code could be improved :-)
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ChunkedZipTwo {
static final long MAX_LIMIT = 10 * 1000 * 1024; //10MB limit - hopefully this
public static void main(String[] args) throws Exception {
String[] files = {"file1", "file2", "file3"};
int i = 0;
boolean needNewFile = false;
long overallSize = 0;
ZipOutputStream out = getOutputStream(i);
byte[] buffer = new byte[1024];
for (String thisFileName : files) {
if (overallSize > MAX_LIMIT) {
out.close();
i++;
out = getOutputStream(i);
overallSize = 0;
}
FileInputStream in = new FileInputStream(thisFileName);
ZipEntry ze = new ZipEntry(thisFileName);
out.putNextEntry(ze);
int len;
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
out.closeEntry();
in.close();
overallSize += ze.getCompressedSize();
}
out.close();
}
public static ZipOutputStream getOutputStream(int i) throws IOException {
ZipOutputStream out = new ZipOutputStream(new FileOutputStream("bigfile" + i + ".zip"));
out.setLevel(Deflater.DEFAULT_COMPRESSION);
return out;
}
}