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 |
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 |
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 |
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);
}
}
}
Thanks a lot.... this really helped me.
ReplyDeleteI 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?
ReplyDeleteHello! I adapted the code to my programm, but Java throws me the following exception:
ReplyDeleteException 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.
I am also getting the same error, what is the solution for this Ana Zerpa
Deletethank you... it helped me alot
ReplyDeletethank you... it helped me alot
ReplyDeletehi,
ReplyDeletehow i can write the condition if any file is in already in zip format then this program will not touch that type of file .
What is the solution of this below error which I am getting by using the above code...
ReplyDeleteException 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)