How To Create A Zip File In Java
How to create Zip file in Java
This article shows a few examples to zip a single file and a whole directory (including sub-files and subdirectories).
- Zip a file –
java.util.zip
- Zip a file –
Files.copy
toZip FileSystems
- Zip a file on demand (without write to disk)
- Zip a folder – File tree and
java.util.zip
- Zip a folder – File tree and
Files.copy
toZip FileSystems
-
zipj4
library
Java 7 introduced the Zip File System Provider, combines with Files.copy
, we can copy the file attributes into the zip file easily (see example 4).
1. Zip a single file – java.util.zip
1.1 This Java example uses java.util.zip.ZipOutputStream
to zip a single file.
ZipFileExample1.java
package com.mkyong.io.howto; import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ZipFileExample1 { public static void main(String[] args) { Path source = Paths.get("/home/mkyong/test/Test.java"); String zipFileName = "example.zip"; try { ZipExample.zipSingleFile(source, zipFileName); } catch (IOException e) { e.printStackTrace(); } System.out.println("Done"); } // Zip a single file public static void zipSingleFile(Path source, String zipFileName) throws IOException { if (!Files.isRegularFile(source)) { System.err.println("Please provide a file."); return; } try ( ZipOutputStream zos = new ZipOutputStream( new FileOutputStream(zipFileName)); FileInputStream fis = new FileInputStream(source.toFile()); ) { ZipEntry zipEntry = new ZipEntry(source.getFileName().toString()); zos.putNextEntry(zipEntry); byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) > 0) { zos.write(buffer, 0, len); } zos.closeEntry(); } } }
Output
Terminal
$ unzip -l example.zip Archive: example.zip Length Date Time Name --------- ---------- ----- ---- 32 2020-08-06 16:19 Test.java --------- ------- 32 1 file $ unzip example.zip Archive: example.zip inflating: Test.java
2. Zip a single file – FileSystems
2.1 This example uses the Java 7 NIO FileSystems.newFileSystem
to create a zip file and Files.copy
to copy the files into the zip path.
ZipFileExample2.java
package com.mkyong.io.howto; import java.io.*; import java.net.URI; import java.nio.file.*; import java.util.HashMap; import java.util.Map; public class ZipFileExample2 { public static void main(String[] args) { Path source = Paths.get("/home/mkyong/test/Test.java"); String zipFileName = "example.zip"; try { ZipExample.zipSingleFileNio(source, zipFileName); } catch (IOException e) { e.printStackTrace(); } System.out.println("Done"); } // Zip a single file public static void zipSingleFileNio(Path source, String zipFileName) throws IOException { if (!Files.isRegularFile(source)) { System.err.println("Please provide a file."); return; } Map<String, String> env = new HashMap<>(); // Create the zip file if it doesn't exist env.put("create", "true"); URI uri = URI.create("jar:file:/home/mkyong/" + zipFileName); try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) { Path pathInZipfile = zipfs.getPath(source.getFileName().toString()); // Copy a file into the zip file path Files.copy(source, pathInZipfile, StandardCopyOption.REPLACE_EXISTING); } } }
3. Zip a single file on demand
This example uses ByteArrayInputStream
to directly create some bytes on demand and save it into the zip file without saving or writing the data into the local file system.
// create a file on demand (without save locally) and add to zip public static void zipFileWithoutSaveLocal(String zipFileName) throws IOException { String data = "Test data \n123\n456"; String fileNameInZip = "abc.txt"; try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFileName))) { ZipEntry zipEntry = new ZipEntry(fileNameInZip); zos.putNextEntry(zipEntry); ByteArrayInputStream bais = new ByteArrayInputStream(data.getBytes()); // one line, able to handle large size? //zos.write(bais.readAllBytes()); // play safe byte[] buffer = new byte[1024]; int len; while ((len = bais.read(buffer)) > 0) { zos.write(buffer, 0, len); } zos.closeEntry(); } }
Output
Terminal
$ unzip -l example.zip Archive: example.zip Length Date Time Name --------- ---------- ----- ---- 18 2020-08-11 18:44 abc.txt --------- ------- 18 1 file
4. Zip a folder or directory – java.util.zip
4.1 Review a directory that includes some sub-files and subdirectories.
Terminal
$ tree /home/mkyong/test test ├── data │ └── db.debug.conf ├── README.md ├── test-a1.log ├── test-a2.log ├── test-b │ ├── test-b1.txt │ ├── test-b2.txt │ ├── test-c │ │ ├── test-c1.log │ │ └── test-c2.log │ └── test-d │ ├── test-d1.log │ └── test-d2.log └── Test.java
4.2 This Java example uses FileVisitor
to walk a file tree and ZipOutputStream
to zip everything manually, including sub-files and subdirectories, but ignore symbolic links and file attributes.
ZipDirectoryExample1.java
package com.mkyong.io.howto; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ZipDirectoryExample { public static void main(String[] args) { Path source = Paths.get("/home/mkyong/test/"); if (!Files.isDirectory(source)) { System.out.println("Please provide a folder."); return; } try { ZipDirectoryExample.zipFolder(source); } catch (IOException e) { e.printStackTrace(); } System.out.println("Done"); } // zip a directory, including sub files and sub directories public static void zipFolder(Path source) throws IOException { // get folder name as zip file name String zipFileName = source.getFileName().toString() + ".zip"; try ( ZipOutputStream zos = new ZipOutputStream( new FileOutputStream(zipFileName)) ) { Files.walkFileTree(source, new SimpleFileVisitor<>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) { // only copy files, no symbolic links if (attributes.isSymbolicLink()) { return FileVisitResult.CONTINUE; } try (FileInputStream fis = new FileInputStream(file.toFile())) { Path targetFile = source.relativize(file); zos.putNextEntry(new ZipEntry(targetFile.toString())); byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) > 0) { zos.write(buffer, 0, len); } // if large file, throws out of memory //byte[] bytes = Files.readAllBytes(file); //zos.write(bytes, 0, bytes.length); zos.closeEntry(); System.out.printf("Zip file : %s%n", file); } catch (IOException e) { e.printStackTrace(); } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed(Path file, IOException exc) { System.err.printf("Unable to zip : %s%n%s%n", file, exc); return FileVisitResult.CONTINUE; } }); } } }
Output
Terminal
Zip file : /home/mkyong/test/test-a2.log Zip file : /home/mkyong/test/test-a1.log Zip file : /home/mkyong/test/data/db.debug.conf Zip file : /home/mkyong/test/README.md Zip file : /home/mkyong/test/Test.java Zip file : /home/mkyong/test/test-b/test-b1.txt Zip file : /home/mkyong/test/test-b/test-c/test-c2.log Zip file : /home/mkyong/test/test-b/test-c/test-c1.log Zip file : /home/mkyong/test/test-b/test-b2.txt Zip file : /home/mkyong/test/test-b/test-d/test-d2.log Zip file : /home/mkyong/test/test-b/test-d/test-d1.log Done
The above example creates the zip file at the current working directory, and we didn't copy the file attributes (review the file created date and time).
Terminal
$ unzip -l test.zip Archive: test.zip Length Date Time Name --------- ---------- ----- ---- 0 2020-08-06 18:49 test-a2.log 0 2020-08-06 18:49 test-a1.log 14 2020-08-06 18:49 data/db.debug.conf 42 2020-08-06 18:49 README.md 32 2020-08-06 18:49 Test.java 0 2020-08-06 18:49 test-b/test-b1.txt 0 2020-08-06 18:49 test-b/test-c/test-c2.log 0 2020-08-06 18:49 test-b/test-c/test-c1.log 0 2020-08-06 18:49 test-b/test-b2.txt 0 2020-08-06 18:49 test-b/test-d/test-d2.log 0 2020-08-06 18:49 test-b/test-d/test-d1.log --------- ------- 88 11 files
5. Zip a folder or directory – FileSystems
5.1 This example uses the same FileVisitor
to walk the file tree. Still, this time we use FileSystems
URI to create the zip file, and Files.copy
to copy the files into the zip path, including the file attributes, but ignore the symbolic link.
ZipDirectoryExample2.java
package com.mkyong.io.howto; import java.io.File; import java.io.IOException; import java.net.URI; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.util.HashMap; import java.util.Map; public class ZipDirectoryExample { public static void main(String[] args) { Path source = Paths.get("/home/mkyong/test/"); if (!Files.isDirectory(source)) { System.out.println("Please provide a folder."); return; } try { ZipDirectoryExample.zipFolderNio(source); } catch (IOException e) { e.printStackTrace(); } System.out.println("Done"); } public static void zipFolderNio(Path source) throws IOException { // get current working directory String currentPath = System.getProperty("user.dir") + File.separator; // get folder name as zip file name // can be other extension, .foo .bar .whatever String zipFileName = source.getFileName().toString() + ".zip"; URI uri = URI.create("jar:file:" + currentPath + zipFileName); Files.walkFileTree(source, new SimpleFileVisitor<>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) { // Copying of symbolic links not supported if (attributes.isSymbolicLink()) { return FileVisitResult.CONTINUE; } Map<String, String> env = new HashMap<>(); env.put("create", "true"); try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) { Path targetFile = source.relativize(file); Path pathInZipfile = zipfs.getPath(targetFile.toString()); // NoSuchFileException, need create parent directories in zip path if (pathInZipfile.getParent() != null) { Files.createDirectories(pathInZipfile.getParent()); } // copy file attributes CopyOption[] options = { StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES, LinkOption.NOFOLLOW_LINKS }; // Copy a file into the zip file path Files.copy(file, pathInZipfile, options); } catch (IOException e) { e.printStackTrace(); } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed(Path file, IOException exc) { System.err.printf("Unable to zip : %s%n%s%n", file, exc); return FileVisitResult.CONTINUE; } }); } }
Output
Terminal
$ unzip -l test.zip Archive: test.zip Length Date Time Name --------- ---------- ----- ---- 0 2020-07-27 15:10 test-a2.log 0 2020-07-23 14:55 test-a1.log 0 2020-08-06 18:57 data/ 14 2020-08-04 14:07 data/db.debug.conf 42 2020-08-05 19:04 README.md 32 2020-08-05 19:04 Test.java 0 2020-08-06 18:57 test-b/ 0 2020-07-24 15:49 test-b/test-b1.txt 0 2020-08-06 18:57 test-b/test-c/ 0 2020-07-27 15:11 test-b/test-c/test-c2.log 0 2020-07-27 15:11 test-b/test-c/test-c1.log 0 2020-07-27 15:10 test-b/test-b2.txt 0 2020-08-06 18:57 test-b/test-d/ 0 2020-07-27 15:11 test-b/test-d/test-d2.log 0 2020-07-27 15:11 test-b/test-d/test-d1.log --------- ------- 88 15 files # unzip to an external folder abc $ unzip test.zip -d abc Archive: test.zip inflating: abc/test-a2.log inflating: abc/test-a1.log creating: abc/data/ inflating: abc/data/db.debug.conf inflating: abc/README.md inflating: abc/Test.java creating: abc/test-b/ inflating: abc/test-b/test-b1.txt creating: abc/test-b/test-c/ inflating: abc/test-b/test-c/test-c2.log inflating: abc/test-b/test-c/test-c1.log inflating: abc/test-b/test-b2.txt creating: abc/test-b/test-d/ inflating: abc/test-b/test-d/test-d2.log inflating: abc/test-b/test-d/test-d1.log $ tree abc abc ├── data │ └── db.debug.conf ├── README.md ├── test-a1.log ├── test-a2.log ├── test-b │ ├── test-b1.txt │ ├── test-b2.txt │ ├── test-c │ │ ├── test-c1.log │ │ └── test-c2.log │ └── test-d │ ├── test-d1.log │ └── test-d2.log └── Test.java
6. Zip file – zip4j
The zip4j
is a popular zip library in Java; it has many advanced features like a password-protected zip file, split zip file, AES encryption, etc. Please visit the zip4j github for further documentation and usages.
Here's are some common usages to zip files and folder.
import net.lingala.zip4j.ZipFile; //... public static void zip4j() throws IOException { // zip file with a single file new ZipFile("filename.zip").addFile("file.txt"); // zip file with multiple files List<File> files = Arrays.asList( new File("file1.txt"), new File("file2.txt")); new ZipFile("filename.zip").addFiles(files); // zip file with a folder new ZipFile("filename.zip").addFolder(new File("/home/mkyong/folder")); }
Download Source Code
References
- Zip File System Provider
- ZIP File Format Specification
- FileVisitor JavaDoc
- How to get the current working directory in Java
- ZipOutputStream JavaDoc
- zip4j github
- How to unzip a zip file in Java
Comments
How To Create A Zip File In Java
Source: https://mkyong.com/java/how-to-compress-files-in-zip-format/
Posted by: guntergeopenceed.blogspot.com
0 Response to "How To Create A Zip File In Java"
Post a Comment