How to create a ZIP File in Java? ZipEntry and ZipOutputStream Compression Example

Since compressing and archiving old log file is an essential housekeeping job in any Java application environment, a Java programmer should know how to compress files in .zip format and then how to read them programmatically if required. The JDK provides full support to create and read ZIP files in Java. There is a separate package java.util.zip to hold all classes related zipping and unzipping files and streams. In this series of article, you will learn how to use those classes e.g. ZipFile, ZipEntry, ZipInputStream, and ZipOutputStream etc. This is the second article about how to work with compressed archives in Java e.g. .zip files. In the last article, I have shown you how to read ZIP archives in Java and today, I'll teach you how to compress files in the ZIP file format by yourself using a Java program. You will compress a bunch of text file to create a .zip file by using JDK's ZIP file support classes.

You create a .zip file in Java to archive files and directory in the compressed format. The JDK (Java Development Kit) provides necessary classes to make a zip file in java.util.zip package. You case use ZipEntry, ZipFile, and ZipOutputStream classes to compress files and create a zip archive. But before that, let's some important classes and their functions.

  • java.util.zip.ZipFile - This class is used to read entries from a zip file. 
  • java.util.zip.ZipEntry - This class is used to represent a ZIP file entry.
  • java.util.zip.ZipInputStream - This class implements an input stream filter for reading files in the ZIP file format. Includes support for both compressed and uncompressed entries.
  • java.util.zip.ZipOutPutStream - This class implements an output stream filter for writing files in the ZIP file format. Includes support for both compressed and uncompressed entries.

Btw, the java.util.zip package not only provides classes to read and write files compressed in ZIP format, but also classes to read/write GZIP format classes as well e.g. GZIPInputStream and GZIPOutputStream. We'll learn about them in some upcoming tutorials. If you are curious about them just now then reading Core Java For The Impatient by Cay S. Horstmann.


Unlike there were two ways to read ZIP file in Java e.g. by using ZipInputStream and ZipFile, there is only one way to create Zip file in Java i.e. by using ZipOutputStream. This class writes data to an output stream in the ZIP file format. If you want to store data in a file, you must chain ZipOutputStream to a FileOutputStream, similar to what we do in Decorator pattern.

Once you create the zip output stream, the next step will be to open source text files which you want to compress. You have to create a zip entry for each file using the java.util.zip.ZipEntry class and before you write the data to stream, you must first put the zip entry object using the putNextEntry() method of ZipOutputStream. Once this is done, you can write the data and close the stream.

So, these were the three steps you need to follow to compress a text file and create a ZIP file in Java i.e.
  1. Create a FileOutputStream to create zip file
  2. Pass that FileOutputStream to ZipOutputStream to write data in zipping file format. 
  3. Optionally you can wrap FileOutputStream into BufferedOutputStream for better write performance.
  4. Open each source file using File class
  5. Create a ZipEntry by using those File objects
  6. Put the ZipEntry into ZipOutputStream using putNextEntry() method
  7. write the data to the ZIP file using write() method of ZipOutputStream.
  8. close the stream

We'll see the complete code example of creating a zip file in Java in next section to see these steps in action.




How to Create a Zip file in Java Code

Here is our complete Java program to package files in a ZIP file in Java. In this program, we have a couple of text files and a directory with a file in the Eclipse project directory. We'll compress those files and directory to create a compressed file in ZIP file format. You can use this file similar to the .zip file created WinZip or WinRAR utility which archives files using ZIP format. You can even open them using any zip tool e.g. Winzip, WinRAR, or 7Zip etc.

Anyway, here is the screen shot of the files and directory which will be compressed to create a ZIP file in Java:
How to create a ZIP File Format in Java?

The files which will be compressed are names.txt, java7.txt, and java.txt. I'll also include the directory targetrr, which contains an apache.txt file, just to demonstrate that you can also include subdirectories with files while zipping them.  Unfortunately, these files are not large so you won't see the effect of compression e.g. compressing a 1GB text file to create a ZIP file in KB, but you can do that yourself. Just copy the log file you want to compress in the archive directory and run the program.


Java Program to create ZIP File in Java
package demo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Java Program to demonstrate how to create ZIP file in Java. ZIP file contains
 * individual files in compressed format.
 * 
 * @author java67
 */

public class FileCopyDemo {

    public static void main(String args[]) {

        try {
            // let's create a ZIP file to write data
            FileOutputStream fos = new FileOutputStream("sample.zip");
            ZipOutputStream zipOS = new ZipOutputStream(fos);

            String file1 = "names.txt";
            String file2 = "java7.txt";
            String file3 = "targetrr/apache.txt";
            String file4 = "java.txt";

            writeToZipFile(file1, zipOS);
            writeToZipFile(file2, zipOS);
            writeToZipFile(file3, zipOS);
            writeToZipFile(file4, zipOS);

            zipOS.close();
            fos.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * Add a file into Zip archive in Java.
     * 
     * @param fileName
     * @param zos
     * @throws FileNotFoundException
     * @throws IOException
     */
    public static void writeToZipFile(String path, ZipOutputStream zipStream)
            throws FileNotFoundException, IOException {

        System.out.println("Writing file : '" + path + "' to zip file");

        File aFile = new File(path);
        FileInputStream fis = new FileInputStream(aFile);
        ZipEntry zipEntry = new ZipEntry(path);
        zipStream.putNextEntry(zipEntry);

        byte[] bytes = new byte[1024];
        int length;
        while ((length = fis.read(bytes)) >= 0) {
            zipStream.write(bytes, 0, length);
        }

        zipStream.closeEntry();
        fis.close();
    }
}

Ouput :
Writing file : 'names.txt' to zip file
Writing file : 'java7.txt' to zip file
Writing file : 'targetrr/apache.txt' to zip file
Writing file : 'java.txt' to zip file


If you open this ZIP file in your machine using WinZIP or WinRAR you can see that it contains all three files and the single directory with a file we have just added, as shown below:

ZipFile, ZipEntry and ZipOutputStream Compression Example


Important Points

Some useful important points related to compression, archiving, and how to work with compressed files e.g. ZIP and GZIP files in Java:

1) Compression and archiving are two different things, but in Windows tools, like Winzip does both i.e. they compress the files and archive them into a separate file.

2) In UNIX, you have to use separate commands for archiving and compression e.g. tar command is used for archiving and gzip is used to compress the archived file.

3) Files added to a ZIP/JAR file are compressed individually

4) The JDK support both ZIP and GZIP file formats, It provides classes to read, create and modify ZIP and GZIP file formats. For example,  you can use ZipInputStream /ZipOutputStream to read/write ZIP file format and GZIPInputStream and GZIPOutputStream to read/write compressed data in GZIP file format.


That's all about how to create a zip file in Java. It's similar to creating a zip file in windows by using the Winzip tool. You can use this program to archive old log files to save some space on your Web Server. You can also enhance this program to accept the input and output location i.e. the location to pick files and where to create the output files. You can read more about compression and archive in Java on Java: How to Program by Deitel and Deitel, one of the most complete books in Java, which covers almost everything from core Java to Swing to JDBC.



Related Java Tutorials


No comments:

Post a Comment