Creating a zip file is a task that can easily be accomplished by using the classes ZipOutputStream and ZipEntry in the java.util.zip package.
First of all, I'm going to present to you a complete code snippet that will create a zip file containing all the files of a specified directory. The resulting zip file has the same name as the given directory, with the .zip extention. The archive will be a valid zip file which can be opened with almost all standard zip archivers, such as WinZip.
Here is the complete code - read on, after the code I'll explain some parts in detail.
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.zip.CRC32; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class CreateZipFile { private final int BUFFER_SIZE = 4096; public void addFileToZip(ZipOutputStream zos, File file) { byte [] data = new byte[BUFFER_SIZE]; int len; FileInputStream fis = null; try { ZipEntry entry = new ZipEntry(file.getName()); entry.setSize(file.length()); entry.setTime(file.lastModified()); zos.putNextEntry(entry); fis = new FileInputStream(file); CRC32 crc32 = new CRC32(); while ((len = fis.read(data)) > -1) { zos.write(data, 0, len); crc32.update(data, 0, len); } entry.setCrc(crc32.getValue()); zos.closeEntry(); } catch (IOException ioe) { ioe.printStackTrace(); } finally { try { if (fis != null) { fis.close(); } } catch (IOException ioe) { ioe.printStackTrace(); } } } public void createZipFile(String directory) { File dir = new File(directory); if (dir.isDirectory()) { File [] files = dir.listFiles(); if (files != null) { File zip = new File(dir.getName() + ".zip"); FileOutputStream fos = null; ZipOutputStream zos = null; try { fos = new FileOutputStream(zip); zos = new ZipOutputStream(fos); zos.setMethod(ZipOutputStream.DEFLATED); for (int i = 0; i < files.length; i++) { if (files[i].isFile()) { System.out.println("Zipping " + files[i].getName()); addFileToZip(zos, files[i]); } } } catch (FileNotFoundException fnfe) { fnfe.printStackTrace(); } finally { if (zos != null) { try { zos.close(); } catch (IOException ioe) { ioe.printStackTrace(); } } if (fos != null) { try { fos.close(); } catch (IOException ioe) { ioe.printStackTrace(); } } } } } else { System.out.println(dir.getName() + " is not a directory"); } } public static void main(String [] args) { if (args.length == 1) { CreateZipFile czf = new CreateZipFile(); czf.createZipFile(args[0]); } else { System.out.println("usage: java CreateZipFile directory"); } } }
The steps that you need to take in order to create a zip file are the following:
- open an OutputStream (for example a FileOutputStream)
- open a ZipOutputStream
- prepare a ZipEntry for each file you would like to add to the zip
- write the file data to the prepared ZipEntry
- close the ZipEntry
- repeat steps 3 through 5 for each additional file you'd like to add
- close the ZipOutputStream
- close the OutputStream
Let's have a look at steps 3 through 5, which need to be repeated for each file.
ZipEntry entry = new ZipEntry(file.getName()); entry.setSize(file.length()); entry.setTime(file.lastModified());
A new ZipEntry is created, the name, size and time of the zipped entity are set. Please note that the CRC32 value is not set at this moment. We'll see later on why this is.
zos.putNextEntry(entry); fis = new FileInputStream(file);
The entry has now been added to a ZipOutputStream which was passed to this method as an argument. An InputStream is opened to read the contents of the file we would like to zip.
CRC32 crc32 = new CRC32(); while ((len = fis.read(data)) > -1) { zos.write(data, 0, len); crc32.update(data, 0, len); } entry.setCrc(crc32.getValue());
We did not set the CRC32 value when we created the ZipEntry. Now we can make up for this: while we add the data to the ZipOutputStream, we calculate the CRC32 value. The benefit of this approach is that we only need to read the contents of the file once, whereas we would have had to read the file twice should we have wanted to do this up front.
zos.closeEntry();
After all this, we only need to close the ZipEntry we added to the ZipOutputStream. We are now ready to add another entry, or we can close the zip file at this point.
Perhaps a final note on the BUFFER_SIZE I used in this example. It is possible to use a smaller or larger buffer size in the example, but please note that setting a size that's too big or too small will hurt performance.
http://jcsnippets.atspace.com/java/input-output/create-zip-file.html