Thomas Sundberg

August 21, 2015

Packaging a zip file from Java using Apache Commons compress

Filed under: Gradle, Java, Programming — Tags: , , — Thomas Sundberg @ 16:10

This post has been migrated to

How do you create a zip file with Java? One option is to use Apache Commons Compress.

This example shows you how.

I use Gradle to define dependencies needed as well as building the example.

The files needed are these:

|-- build.gradle
`-- src
    `-- test
        |-- java
        |   `-- se
        |       `-- thinkcode
        |           `-- zip
        |               `--
        `-- resources
            `-- readme.txt

Three different files.

Project file

Create a Gradle project file with this content:


apply plugin: "java" repositories { mavenCentral() } dependencies { compile 'org.apache.commons:commons-compress:1.9' compile 'commons-io:commons-io:2.4' testCompile 'junit:junit:4.12' }

This defines the dependencies I use. Most notably org.apache.commons:commons-compress:1.9 that will do the heavy lifting.

The implementation

The implementation is then done in a test class. I am a fan of test driven development so I wrote a test that will package the content of a directory and then verify that one file was packed.

It looks like this:


package; import org.apache.commons.compress.archivers.ArchiveException; import org.apache.commons.compress.archivers.ArchiveOutputStream; import org.apache.commons.compress.archivers.ArchiveStreamFactory; import; import; import org.apache.commons.compress.utils.IOUtils; import; import org.junit.Test; import*; import java.util.Collection; import java.util.Enumeration; import static; import static org.junit.Assert.*; public class ZipFileTest { @Test public void add_all_files_from_a_directory_to_a_zip_archive() throws Exception { File source = new File("build/resources/test"); File destination = new File("build/"); destination.delete(); addFilesToZip(source, destination); assertTrue("Expected to find the zip file ", destination.exists()); assertZipContent(destination); } /** * Add all files from the source directory to the destination zip file * * @param source the directory with files to add * @param destination the zip file that should contain the files * @throws IOException if the io fails * @throws ArchiveException if creating or adding to the archive fails */ private void addFilesToZip(File source, File destination) throws IOException, ArchiveException { OutputStream archiveStream = new FileOutputStream(destination); ArchiveOutputStream archive = new ArchiveStreamFactory().createArchiveOutputStream(ArchiveStreamFactory.ZIP, archiveStream); Collection<File> fileList = FileUtils.listFiles(source, null, true); for (File file : fileList) { String entryName = getEntryName(source, file); ZipArchiveEntry entry = new ZipArchiveEntry(entryName); archive.putArchiveEntry(entry); BufferedInputStream input = new BufferedInputStream(new FileInputStream(file)); IOUtils.copy(input, archive); input.close(); archive.closeArchiveEntry(); } archive.finish(); archiveStream.close(); } /** * Remove the leading part of each entry that contains the source directory name * * @param source the directory where the file entry is found * @param file the file that is about to be added * @return the name of an archive entry * @throws IOException if the io fails */ private String getEntryName(File source, File file) throws IOException { int index = source.getAbsolutePath().length() + 1; String path = file.getCanonicalPath(); return path.substring(index); } private void assertZipContent(File destination) throws IOException { ZipFile zipFile = new ZipFile(destination); ZipArchiveEntry readme = zipFile.getEntry("readme.txt"); assertNotNull(readme); Enumeration<ZipArchiveEntry> entries = zipFile.getEntries(); int numberOfEntries = 0; while (entries.hasMoreElements()) { numberOfEntries++; entries.nextElement(); } assertThat(numberOfEntries, is(1)); } }

The work is done in addFilesToZip.

I like the idea of Tdd as if you meant it and this was the result from my implementation. Your job, if you want to use this solution, is to extract the methods needed and possibly modify them to suit you needs.


Building this project requires you to have Gradle installed. When you have installed a modern version of Gradle, 2.6 when this is written, you build the example by executing

    gradle test

in the same directory as you have build.gradle. The dependencies needed will be downloaded and the test that packages one file will be executed.


Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at

%d bloggers like this: