In this article, we will see how to compress data to a zip file using java.util.zip
package. Classes in the java.util.zip
package allow you to read, create, and modify ZIP and GZIP file formats. It also provides utility classes for computing checksums of arbitrary input streams that can be used to validate input data.
Checksum
In this example, we will compress files and add them to an archive. If you want to send the zipped file to a remote location using checksum value of the zip file one can figure whether the received file is intact or corrupted.
A checksum or hash sum is a small-size datum from a block of digital data for the purpose of detecting errors which may have been introduced during its transmission or storage. The algorithm that computes the checksum on a given data input is called a checksum function. If the computed checksum for the sent zip file doesn’t match with the checksum of the decompressed zip file then there is a very high probability the data has not been accidentally altered or corrupted.
Compressing files to a ZIP File
We will introduce here some of the important classes in the java.util.zip
package.
ZipOutputStream
– Writes data to an output stream in a ZIP format.CheckedOutputStream
– An output stream that maintains the checksum of the data being writtenAdler32
– Implement thejava.util.zip.Checksum
interface and computes the checksum required for data compression.. The other implementation isCRC32
ZipEntry
– Represents a zip file entry
Now that we know the classes involved, lets look into the steps.
- Since we want to write data to a zip file, we need to first create a
ZipOutputStream
object, to which we pass the output stream of the file we wish to write to.FileOutputStream dest = new FileOutputStream("allFiles.zip"); ZipOutputStream zos = new ZipOutputStream(dest);
- We also want to compute checksum, so we create a
CheckedOutputStream
object using the file output stream and then passCheckedOutputStream
object while creating theZipOutputStream
object.FileOutputStream dest = new FileOutputStream("allFiles.zip"); CheckedOutputStream checksum = new CheckedOutputStream(dest, new Adler32()); ZipOutputStream zos = new ZipOutputStream(checksum);
- Once the target zip output stream is created, the next step is to open each source data file that want to be part of the zip file.
String[] zipEntryFiles = new String[] { "emp.xml", "x.properties", "y.txt" }; ... for (String zipEntryFile : zipEntryFiles) { BufferedInputStream bis = new BufferedInputStream( FileCompressionExample.class .getResourceAsStream(zipEntryFile)); try { ... } finally { ... } }
- Before we can write data to the ZIP output stream, we must first put the zip entry object using the
putNextEntry()
method.String fileName = "com/javarticles/io/" + zipEntryFile; ZipEntry entry = new ZipEntry(fileName); System.out.println("Adding file: " + fileName); zos.putNextEntry(entry);
- Write the data to the ZIP file.
int count; while ((count = bis.read(data, 0, data.length)) != -1) { bos.write(data, 0, count); }
- Finally flush the output stream and close the source stream.
try { ... while ((count = bis.read(data, 0, data.length)) != -1) { bos.write(data, 0, count); } } finally { bis.close(); bos.flush(); }
Just to spice up the example, we will add three different types of file to the zip file. An xml, a property file and a text file.
emp.xml:
<?xml version="1.0"?> <employees> <employee id="1"> <name>Joe</name> <age>34</age> </employee> <employee id="2"> <name>Sam</name> <age>24</age> </employee> <employee id="3"> <name>John<!-- author --> S</name> <age>44</age> </employee> </employees>
x.properties:
name=javarticles.com
y.txt:
Hello!
FileCompressionExample:
package com.javarticles.io; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.zip.Adler32; import java.util.zip.CheckedOutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class FileCompressionExample { public static void main(String[] args) throws IOException { String[] zipEntryFiles = new String[] { "emp.xml", "x.properties", "y.txt" }; FileOutputStream dest = new FileOutputStream("allFiles.zip"); CheckedOutputStream checksum = new CheckedOutputStream(dest, new Adler32()); ZipOutputStream zos = new ZipOutputStream(checksum); BufferedOutputStream bos = new BufferedOutputStream(zos); try { zos.setComment("Javaticles - Compressing files example"); byte[] data = new byte[1024]; for (String zipEntryFile : zipEntryFiles) { BufferedInputStream bis = new BufferedInputStream( FileCompressionExample.class .getResourceAsStream(zipEntryFile)); try { String fileName = "com/javarticles/io/" + zipEntryFile; ZipEntry entry = new ZipEntry(fileName); System.out.println("Adding file: " + fileName); zos.putNextEntry(entry); int count; while ((count = bis.read(data, 0, data.length)) != -1) { bos.write(data, 0, count); } } finally { bis.close(); bos.flush(); } } System.out .println("checksum: " + checksum.getChecksum().getValue()); } catch (Exception e) { e.printStackTrace(); } finally { bos.close(); } } }
The computed checksum must match the checksum computed as we decompress the files.
Output:
Adding file: com/javarticles/io/emp.xml Adding file: com/javarticles/io/x.properties Adding file: com/javarticles/io/y.txt checksum: 3365432775
Download the source code
This was an example about compressing data files to a zip file.