Closing ZipOutputStream
You should close the FileOutputStream
, not the ZipOutputStream
, because the former is what actually consumes system resources.
File zipFile = new File("/tmp/example.zip");
FileOutputStream fos = null;
try
{
fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
// ...
zos.close();
}
catch (IOException ex)
{
// log/report exception, then delete the invalid file
IOUtils.closeQuietly(fos);
zipFile.delete();
}
finally
{
IOUtils.closeQuietly(fos);
}
The IOUtils
class is found in Jakarta Commons IO. Using it means that you don't have to deal with the possible-but-rarely-useful IOException
that can be thrown by close()
.
Instead of closing the stream only when things are added, what I did is a condition check to see if there was anything to zip, before running the zip code. This helped me to simplify the process and I think can be used in general to handle the "ZIP file must have at least one entry" problem. True that closing zos
may throw other exceptions, but that is rare.
I think it is problem with Java, that doesn't handle the case when there are no files to zip.
i.e:
int itemsToAdd=0;
//....
if ( itemsToAdd > 0 ) {
ZipOutputStream zos = new ZipOutputStream(file);
try {
//add files to zip
}
finally {
zos.close();
}
}
You should track if you added stuff the zip stream and close it only when things were added:
ZipOutputStream zos = null;
OutputStream file = new FileOutputStream("...")
int itemsAdded=0;
try
{
zos = new ZipOutputStream(file);
//
//..
// itemsAdded++;
}
finally
{
if ( itemsAdded > 0 ) {
zos.close();
} else {
file.close();
}
}
of if you don't need the count just use a boolean
flag.