Add Files to Existing ZIP Archive in Java – Example Program

In this tutorial, we will see how to add a file to an existing ZIP file, using Java, with an example. We will use Java NIO’s new feature ZIP File System Provider to append files to existing files. ZIP File System Provider is capable of treating a ZIP File as a File System. This would mean adding files to an existing archive would be as straight forward as copying a file from your disk to the file system using methods available in NIO class. Getting curious? Let us take you through a step by step guide on how to do this in Java.  The high level steps involved in this example are captured below:

Steps to add a new file to a ZIP Archive in Java
Steps to add a new file to a ZIP Archive in Java

1.Define ZIP File System Properties


In order to create new entries to a ZIP file, you have to start by defining a HashMap, and push properties “create” to false (as we are reading an existing ZIP File) and encoding to the encoding used in the ZIP file. Note that the encoding parameter is optional. The Java code to define the HashMap is provided below:

        /* Define ZIP File System Properies in HashMap */    
        Map<String, String> zip_properties = new HashMap<>(); 
        /* We want to read an existing ZIP File, so we set this to False */
        zip_properties.put("create", "false");
        /* Specify the encoding as UTF -8 */
        zip_properties.put("encoding", "UTF-8");        


2.Access Existing ZIP File


Next, you need to tell the program, where your ZIP file is located. To do this, you create a URI object in Java which points to the actual file on disk. Later, you will know how to create a ZIP File system using the URI Object and the HashMap. The code segment to define a URI object is shown below:

        /* Specify the path to the ZIP File that you want to read as a File System */
        URI zip_disk = URI.create("jar:file:/my_zip_file.zip");


3.Create ZIP File System


Using the HashMap created in step – 1 and the URI object in step-2, we can create a ZIP File System in Java. Once this is done, adding more files to the ZIP file would be a cakewalk. The Java code to create a ZIP file system is show below:


        try (FileSystem zipfs = FileSystems.newFileSystem(zip_disk, zip_properties)) {


4.Append Files to ZIP Archive


Once we have created a ZIP File System, it is very easy to add more files to it. A screenshot of our ZIP file before adding new files is shown below:


Input ZIP File Before Adding New Files
Input ZIP File Before Adding New Files
To add new files to this archive, you have to create a Path object to the file you want to add and use the copy method in Files class to add the file to the archive. You should also define the path in the ZIP file suitably. Here is a code example


             /* Create a Path in ZIP File */
            Path ZipFilePath = zipfs.getPath("TESTER.zip");
            /* Path where the file to be added resides */
            Path addNewFile = Paths.get("C:/temp/TESTER.zip");  
            /* Append file to ZIP File */
            Files.copy(addNewFile,ZipFilePath); 


That is it! Three lines and you are done. Output screenshot of the resulting file is shown below: (new entry in ZIP file is marked in RED

ZIP File with new Entry Added
ZIP File with new Entry Added


5.Complete Program – Add Entries to ZIP File in Java


Putting it all together, the complete Java program that utilizes Zip File System Provider (ZPFS) and NIO to append entries into a ZIP file is shown below:

import java.util.*;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.*;
public class ZPFSAppend {
    public static void main(String [] args) throws Exception {
        /* Define ZIP File System Properies in HashMap */    
        Map<String, String> zip_properties = new HashMap<>(); 
        /* We want to read an existing ZIP File, so we set this to False */
        zip_properties.put("create", "false");
        /* Specify the encoding as UTF -8 */
        zip_properties.put("encoding", "UTF-8");        
        /* Specify the path to the ZIP File that you want to read as a File System */
        URI zip_disk = URI.create("jar:file:/my_zip_file.zip");
        /* Create ZIP file System */
        try (FileSystem zipfs = FileSystems.newFileSystem(zip_disk, zip_properties)) {
             /* Create a Path in ZIP File */
            Path ZipFilePath = zipfs.getPath("TESTER.zip");
            /* Path where the file to be added resides */
            Path addNewFile = Paths.get("C:/temp/TESTER.zip");  
            /* Append file to ZIP File */
            Files.copy(addNewFile,ZipFilePath); 
        } 
    }
}

You can try adding as many entries you want using this approach. Try this code and if you experience any issues, you can post it in the comments section of this blog.

8 comments:

  1. Thanks a lot.... this really helped me.

    ReplyDelete
  2. I am having trouble with the creation of the file system. I think it has to do with the cretion of the URI. How would be the syntax for a file with an absolute path that comes from a string type variable?

    ReplyDelete
  3. Hello! I adapted the code to my programm, but Java throws me the following exception:

    Exception in thread "main" java.util.zip.ZipError: zip END header not found
    at com.sun.nio.zipfs.ZipFileSystem.zerror(ZipFileSystem.java:1605)
    at com.sun.nio.zipfs.ZipFileSystem.findEND(ZipFileSystem.java:1021)
    at com.sun.nio.zipfs.ZipFileSystem.initCEN(ZipFileSystem.java:1030)
    at com.sun.nio.zipfs.ZipFileSystem.(ZipFileSystem.java:130)
    at com.sun.nio.zipfs.ZipFileSystemProvider.newFileSystem(ZipFileSystemProvider.java:117)
    at java.nio.file.FileSystems.newFileSystem(Unknown Source)
    at java.nio.file.FileSystems.newFileSystem(Unknown Source)
    at Tests.main(Tests.java:72)

    I removed the encoding line because it is not relevant to me. Even though Java keeps throwing me the same exception. I also added the first entry with the other method that supposses to rewrite the folder. But nothing. I will appreciate the help. Thanks in advance.

    ReplyDelete
    Replies
    1. I am also getting the same error, what is the solution for this Ana Zerpa

      Delete
  4. thank you... it helped me alot

    ReplyDelete
  5. thank you... it helped me alot

    ReplyDelete
  6. hi,
    how i can write the condition if any file is in already in zip format then this program will not touch that type of file .

    ReplyDelete
  7. What is the solution of this below error which I am getting by using the above code...
    Exception in thread "main" java.util.zip.ZipError: zip END header not found
    at com.sun.nio.zipfs.ZipFileSystem.zerror(ZipFileSystem.java:1605)
    at com.sun.nio.zipfs.ZipFileSystem.findEND(ZipFileSystem.java:1021)
    at com.sun.nio.zipfs.ZipFileSystem.initCEN(ZipFileSystem.java:1030)
    at com.sun.nio.zipfs.ZipFileSystem.(ZipFileSystem.java:130)
    at com.sun.nio.zipfs.ZipFileSystemProvider.newFileSystem(ZipFileSystemProvider.java:117)
    at java.nio.file.FileSystems.newFileSystem(FileSystems.java:326)
    at java.nio.file.FileSystems.newFileSystem(FileSystems.java:276)
    at com.dxc.UpdateZip.main(UpdateZip.java:35)

    ReplyDelete