How to Zip Multiple Pdf Files in Java

Are you looking for the best way to zip multiple pdf files in java? If yes, then you are at the right place. In this tutorial, we’ll go over some of the best ways to do it. Whether your objective is to compress a bunch of image files into a single file or merge multiple files of any type into a single file (zip), there are several readily available tools for doing so.

How to Zip Multiple Pdf Files in Java One place to get an easy answer is writing a program. We can write one such program and use it wherever we want. Here is an example of such utility. We can use this utility to combine pdf, doc, xls, html whatever files into single zip archive.

Zipping a file is one of the most common Java programming topics. Fortunately, there are many utilities out there in Java that will handle this with ease. Here I will discuss the different way you can go about zipping a file or files, and how to zip multiple pdf files in java

When working with large numbers of files, it is useful to be able to package them together into a single file. One you can send as an attachment, save on your hard drive, streamline backups etc. Using Java we can achieve this by creating a compressed archive in the form of a .zip file. Although we could create such a zip file manually, there is already a built-in Java class for creating archive files; ZipFile. In this article, you will learn how to compress files in ZIP format using the java.util.zip package. You know, Java has great support for writing and reading ZIP files via the easy-to-use API. With this feature, you can compress/decompress data on the fly in your Java programs.

Zipping and Unzipping in Java

1. Overview

In this quick tutorial, we’ll learn how to zip a file into an archive and how to unzip the archive, all using core libraries provided by Java.

These core libraries are part of the java.util.zip package, where we can find all zipping and unzipping related utilities.

2. Zip a File

First, let’s have a look at a simple operation, zipping a single file.

For our example, we’ll zip a file named test1.txt into an archive named compressed.zip.

Of course, we’ll first access the file from a disk:

public class ZipFile {
    public static void main(String[] args) throws IOException {
        String sourceFile = "test1.txt";
        FileOutputStream fos = new FileOutputStream("compressed.zip");
        ZipOutputStream zipOut = new ZipOutputStream(fos);
        File fileToZip = new File(sourceFile);
        FileInputStream fis = new FileInputStream(fileToZip);
        ZipEntry zipEntry = new ZipEntry(fileToZip.getName());
        zipOut.putNextEntry(zipEntry);
        byte[] bytes = new byte[1024];
        int length;
        while((length = fis.read(bytes)) >= 0) {
            zipOut.write(bytes, 0, length);
        }
        zipOut.close();
        fis.close();
        fos.close();
    }
}

3. Zip Multiple Files

Next, let’s see how to zip multiple files into one zip file. We’ll compress test1.txt and test2.txt into multiCompressed.zip:

public class ZipMultipleFiles {
    public static void main(String[] args) throws IOException {
        List<String> srcFiles = Arrays.asList("test1.txt", "test2.txt");
        FileOutputStream fos = new FileOutputStream("multiCompressed.zip");
        ZipOutputStream zipOut = new ZipOutputStream(fos);
        for (String srcFile : srcFiles) {
            File fileToZip = new File(srcFile);
            FileInputStream fis = new FileInputStream(fileToZip);
            ZipEntry zipEntry = new ZipEntry(fileToZip.getName());
            zipOut.putNextEntry(zipEntry);

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

4. Zip a Directory

Now let’s discuss how to zip an entire directory. We’ll compress zipTest into dirCompressed.zip :

public class ZipDirectory {
    public static void main(String[] args) throws IOException {
        String sourceFile = "zipTest";
        FileOutputStream fos = new FileOutputStream("dirCompressed.zip");
        ZipOutputStream zipOut = new ZipOutputStream(fos);
        File fileToZip = new File(sourceFile);

        zipFile(fileToZip, fileToZip.getName(), zipOut);
        zipOut.close();
        fos.close();
    }

    private static void zipFile(File fileToZip, String fileName, ZipOutputStream zipOut) throws IOException {
        if (fileToZip.isHidden()) {
            return;
        }
        if (fileToZip.isDirectory()) {
            if (fileName.endsWith("/")) {
                zipOut.putNextEntry(new ZipEntry(fileName));
                zipOut.closeEntry();
            } else {
                zipOut.putNextEntry(new ZipEntry(fileName + "/"));
                zipOut.closeEntry();
            }
            File[] children = fileToZip.listFiles();
            for (File childFile : children) {
                zipFile(childFile, fileName + "/" + childFile.getName(), zipOut);
            }
            return;
        }
        FileInputStream fis = new FileInputStream(fileToZip);
        ZipEntry zipEntry = new ZipEntry(fileName);
        zipOut.putNextEntry(zipEntry);
        byte[] bytes = new byte[1024];
        int length;
        while ((length = fis.read(bytes)) >= 0) {
            zipOut.write(bytes, 0, length);
        }
        fis.close();
    }
}

Note that:

  • To zip sub-directories, we iterate through them recursively.
  • Every time we find a directory, we append its name to the descendants ZipEntry name to save the hierarchy.
  • We also create a directory entry for every empty directory.

5. Unzip an Archive

Zip lines are single lines that contain one or further compressed lines. People zip lines to keep affiliated groups of lines together and to make lines lower so they’re easier and faster to partake by dispatch or via the web.
Zip lines are ideal for archiving since they save storehouse space. And, they’re also useful for securing data using encryption.

Now let’s unzip an archive and extract its contents.

For this example, we’ll unzip compressed.zip into a new folder named unzipTest:

public class UnzipFile {
    public static void main(String[] args) throws IOException {
        String fileZip = "src/main/resources/unzipTest/compressed.zip";
        File destDir = new File("src/main/resources/unzipTest");
        byte[] buffer = new byte[1024];
        ZipInputStream zis = new ZipInputStream(new FileInputStream(fileZip));
        ZipEntry zipEntry = zis.getNextEntry();
        while (zipEntry != null) {
           // ...
        }
        zis.closeEntry();
        zis.close();
    }
}

Inside the while loop, we’ll iterate through each ZipEntry and first check if it’s a directory. If it is, then we’ll create the directory using the mkdirs() method; otherwise, we’ll continue with creating the file:

while (zipEntry != null) {
     File newFile = newFile(destDir, zipEntry);
     if (zipEntry.isDirectory()) {
         if (!newFile.isDirectory() && !newFile.mkdirs()) {
             throw new IOException("Failed to create directory " + newFile);
         }
     } else {
         // fix for Windows-created archives
         File parent = newFile.getParentFile();
         if (!parent.isDirectory() && !parent.mkdirs()) {
             throw new IOException("Failed to create directory " + parent);
         }
         
         // write file content
         FileOutputStream fos = new FileOutputStream(newFile);
         int len;
         while ((len = zis.read(buffer)) > 0) {
             fos.write(buffer, 0, len);
         }
         fos.close();
     }
 zipEntry = zis.getNextEntry();
}

One note here is that on the else branch, we’re also checking if the parent directory of the file exists. This is necessary for archives created on Windows, where the root directories don’t have a corresponding entry in the zip file.

Another key point can be seen in the newFile() method:

public static File newFile(File destinationDir, ZipEntry zipEntry) throws IOException {
    File destFile = new File(destinationDir, zipEntry.getName());

    String destDirPath = destinationDir.getCanonicalPath();
    String destFilePath = destFile.getCanonicalPath();

    if (!destFilePath.startsWith(destDirPath + File.separator)) {
        throw new IOException("Entry is outside of the target dir: " + zipEntry.getName());
    }

    return destFile;
}

This method guards against writing files to the file system outside of the target folder. This vulnerability is called Zip Slip, 

Create zip file from multiple files with ZipOutputStream

We can use the ZipOutputStream object for writing files in the zip file format. To create a zip file from multiple files, we perform the following:

  1. Get the path of the files to be zipped.
  2. Get the name for the zip file to be created.
  3. Create a FileOutputStream object for the given zip name.
  4. Create a new ZipOutputStream object using the FileOutputStream object.
  5. Read the provided file and use the putNextEntry and write methods to add that file to the ZipOutputStream object.
  6. Close all the opened streams.

With this example we are going to demonstrate how to create a zip file from multiple Files with ZipOutputStream, that implements an output stream filter for writing files in the ZIP file format. In short, to create a zip file from multiple Files with ZipOutputStream you should:

  • Create a FileOutputStream to write to the file with the specified name, that is the zipFile.
  • Create a new ZipOutputStream from the FileOutputStream, that is an output stream filter for writing files in the ZIP file format.
  • For each one of the Files create a new File instance by the given pathname of the file.
  • Create a FileInputStream by opening a connection to the file.
  • Create a new ZipEntry with the name of the File and begin writing it to the ZipOutputStream. The default compression method will be used if no compression method was specified for the entry.
  • Read up to 1024 bytes of data from the file into an array of bytes, using the read(byte[] b) API method of FileInputStream and write the data to the current ZipEntry data, using write(byte[] b, int off, int len) method of ZipOutputStream.
  • Always remember to close the ZipEntry, the ZipOutputStream and the FileInputStream, using closeEntry() and close() API methods respectively.

Let’s take a look at the code snippet that follows:

0102030405060708091011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859package com.javacodegeeks.snippets.core; import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.util.zip.ZipEntry;import java.util.zip.ZipOutputStream; public class CreateZipFileFromMultipleFilesWithZipOutputStream {         public static void main(String[] args) {                 String zipFile = "C:/archive.zip";                 String[] srcFiles = { "C:/srcfile1.txt", "C:/srcfile2.txt", "C:/srcfile3.txt"};                 try {                         // create byte buffer            byte[] buffer = new byte[1024];             FileOutputStream fos = new FileOutputStream(zipFile);             ZipOutputStream zos = new ZipOutputStream(fos);                         for (int i=0; i < srcFiles.length; i++) {                                 File srcFile = new File(srcFiles[i]);                 FileInputStream fis = new FileInputStream(srcFile);                 // begin writing a new ZIP entry, positions the stream to the start of the entry data                zos.putNextEntry(new ZipEntry(srcFile.getName()));                                 int length;                 while ((length = fis.read(buffer)) > 0) {                    zos.write(buffer, 0, length);                }                 zos.closeEntry();                 // close the InputStream                fis.close();                             }             // close the ZipOutputStream            zos.close();                     }        catch (IOException ioe) {            System.out.println("Error creating zip file: " + ioe);        }             } }

 
This was an example of how to create a zip file from multiple Files with ZipOutputStream in Java.

Zipping single fie in Java using ZipOutputStream

The steps for zipping a file using ZipOutputStream are as follows-

  • Create an InputStream for reading the source file.
  • Create an OutputStream for the zip file and wrap it in a ZipOutputStream object.
  • Create a ZipEntry instance for the source file and add it to the ZipOutputStream.
  • Read data from the source file and write it to the ZIP file.
  • Close the streams.
public class ZipFile {
  public static void main(String[] args) {
    // source file
    String fileName = "F:\\knpcode\\links.txt";
    File file = new File(fileName);
    //Creating zipfile name from fileName by 
    // truncating .txt and appending .zip
    String zipFilename = fileName.substring(0, fileName.indexOf('.')) + ".zip";
    File zipFile = new File(zipFilename);
    zipFile(file, zipFile);
  }
	
  // Method to zip file
  private static void zipFile(File file, File zippedFile){
    final int BUFFER = 1024;
    ZipOutputStream zos = null;
    BufferedInputStream bis = null;
    try{
      FileInputStream fis = new FileInputStream(file);
      bis = new BufferedInputStream(fis, BUFFER);          
      // Creating ZipOutputStream for writing to zip file
      FileOutputStream fos = new FileOutputStream(zippedFile);
      zos = new ZipOutputStream(fos);
      // Each file in the zipped archive is represented by a ZipEntry 
      // Only source file name is needed 
      ZipEntry ze = new ZipEntry(file.getName());        
      zos.putNextEntry(ze);
      byte data[] = new byte[BUFFER];
      int count;
      while((count = bis.read(data, 0, BUFFER)) != -1) {
        zos.write(data, 0, count);
      }                     
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }finally{
      try {
        zos.close();
        bis.close();
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }  
    }
  }
}

Find the right documentation tool for your team

This is by no means an exhaustive list of documentation tools. There are plenty of other solutions, many of which are (quite honestly) almost identical copies of each other.

Writing software documentation is essential, as it showcases the product you have built to the world. Software documentation is the process of creating and maintaining any form of informational support for a software application. When a user downloads your app for the first time, they’re left scratching their heads with no explanation of what this product does and how it should be used. With proper software documentation up-front, you show that interest in your work that would otherwise have been unseen.

Therefore, software documentation tools are a crucial part of the software development process. They help software developers to create, maintain and update the technical documentation for the software products. 

A very powerful and useful tool in any design project, documentation can be defined as a way to pass on knowledge about the project from person to person, team member to team member. We will be discussing various types of Software Documentation Tools that help a developer create technical documentation for a product. 

It’s also important to keep in mind that finding the right tool is only half the battle. The real challenge is to build a culture of documentation and develop the right habits. A user-friendly documentation tool, however, can make that task a lot easier. We hope this list helps you make the right choice for your team.

Conclusion

In Java, the home of the zip and unzip capabilities is in the java.util.zip package. The ZipEntry class contains information about a file inside a zip archive and the FileInputStream is responsible for reading file bytes into a byte array, which we then pass to the ZipOutputStream to output it to a zip file. Creating

Zipping PDF files and converting them to a single zip file makes administering and updating your documents more efficient. Zipping multiple Java files and converting them to a single java file also has powerful advantages.

Leave a Comment