This article is about how to write a utility class for adding files and directories into a compressed zip archive, using built-in Java API.
The java.util.zip package provides the following classes for adding files and directories into a ZIP archive:
ZipOutputStream: this is the main class which can be used for making zip file and adding files and directories (entries) to be compressed in a single archive. Here are some important usages of this class:
ZipEntry: this class represents an entry to be added to the zip file. Its constructor takes a String which represents path of the file/directory being added. The path must be in the following form:
folder_1/subfolder_1/subfolder_2/…/subfolder_n/file.ext
In addition, the BufferedInputStream class is used to read content of input file via its method read(byte[]). While reading file’s content, write the bytes read into the current zip entry via ZipOutputStream’s write() method.
Following is source code of ZipUtility.java class:
import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; /** * This utility compresses a list of files to standard ZIP format file. * It is able to compress all sub files and sub directories, recursively. * @author www.codejava.net * */ public class ZipUtility { /** * A constants for buffer size used to read/write data */ private static final int BUFFER_SIZE = 4096; /** * Compresses a list of files to a destination zip file * @param listFiles A collection of files and directories * @param destZipFile The path of the destination zip file * @throws FileNotFoundException * @throws IOException */ public void zip(List<File> listFiles, String destZipFile) throws FileNotFoundException, IOException { ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(destZipFile)); for (File file : listFiles) { if (file.isDirectory()) { zipDirectory(file, file.getName(), zos); } else { zipFile(file, zos); } } zos.flush(); zos.close(); } /** * Compresses files represented in an array of paths * @param files a String array containing file paths * @param destZipFile The path of the destination zip file * @throws FileNotFoundException * @throws IOException */ public void zip(String[] files, String destZipFile) throws FileNotFoundException, IOException { List<File> listFiles = new ArrayList<File>(); for (int i = 0; i < files.length; i++) { listFiles.add(new File(files[i])); } zip(listFiles, destZipFile); } /** * Adds a directory to the current zip output stream * @param folder the directory to be added * @param parentFolder the path of parent directory * @param zos the current zip output stream * @throws FileNotFoundException * @throws IOException */ private void zipDirectory(File folder, String parentFolder, ZipOutputStream zos) throws FileNotFoundException, IOException { for (File file : folder.listFiles()) { if (file.isDirectory()) { zipDirectory(file, parentFolder + "/" + file.getName(), zos); continue; } zos.putNextEntry(new ZipEntry(parentFolder + "/" + file.getName())); BufferedInputStream bis = new BufferedInputStream( new FileInputStream(file)); long bytesRead = 0; byte[] bytesIn = new byte[BUFFER_SIZE]; int read = 0; while ((read = bis.read(bytesIn)) != -1) { zos.write(bytesIn, 0, read); bytesRead += read; } zos.closeEntry(); } } /** * Adds a file to the current zip output stream * @param file the file to be added * @param zos the current zip output stream * @throws FileNotFoundException * @throws IOException */ private void zipFile(File file, ZipOutputStream zos) throws FileNotFoundException, IOException { zos.putNextEntry(new ZipEntry(file.getName())); BufferedInputStream bis = new BufferedInputStream(new FileInputStream( file)); long bytesRead = 0; byte[] bytesIn = new byte[BUFFER_SIZE]; int read = 0; while ((read = bis.read(bytesIn)) != -1) { zos.write(bytesIn, 0, read); bytesRead += read; } zos.closeEntry(); } }
The ZipUtility class has two public methods for adding files and directories to a zip archive:
And source code of a test class, ZipUtilityTest.java:
/** * A console application that tests the ZipUtility class * @author www.codejava.net * */ public class ZipUtilityTest { public static void main(String[] args) { String[] myFiles = {"E:/Test/PIC1.JPG", "E:/Test/PIC2.JPG", "E:/Test/PIC3.JPG", "E:/Test/PIC4.JPG"}; String zipFile = "E:/Test/MyPics.zip"; ZipUtility zipUtil = new ZipUtility(); try { zipUtil.zip(myFiles, zipFile); } catch (Exception ex) { // some errors occurred ex.printStackTrace(); } } }