In the post How to Zip Files in Java we have seen how to zip a single file or multiple files in Java but you may also need to zip a folder in Java where you also retain the folder tree structure while zipping it. This post shows how to zip a folder in Java where the zip archive contains the whole tree structure (files and subdirectories).
Options for zipping a folder in Java
For zipping a folder with all its subfolders and files two options are given in this post.
- Using Files.walkFileTree() method- Using this method you can recursively visit all the files in a file tree. An implementation of FileVisitor interface is provided to the Files.walkFileTree method to visit each file in a file tree. This option is available Java 7 onward. See example.
- By providing the code yourself to read the files with in a folder recursively by using listFiles() method in java.io.File class. See example.
Check this post How to Unzip a File in Java to see how to unzip files and folders in Java.
Directory structure used
Java programs shown here to zip a folder in Java use the following directory structure.
With in the parent folder there is one sub folder Child with two files and one file is stored in the parent folder. The zipped archive should retain the same tree structure.
Using Files.walkFileTree method to zip a folder in Java
One of the argument of this method is a FileVisitor interface. You do need to provide implementation of this interface as per your requirement. FileVisitor interface has four methods, for zipping a folder you do need to implement two of them.
- preVisitDirectory– Invoked before a directory's entries are visited. By implementing this method you can create the visited folder with in the zip archive.
- visitFile– Invoked on the file being visited. By implementing this method you can add each visited file to the zip archive.
import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.SimpleFileVisitor; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.zip.ZipOutputStream; import java.nio.file.attribute.BasicFileAttributes; import java.util.zip.ZipEntry; public class ZipFolder { public static void main(String[] args) { // Source folder final String SOURCE_DIR = "F:/knpcode/Parent"; // creating the name of the zipped archive String ZIP_DIR = SOURCE_DIR.concat(".zip"); zipFolderStructure(SOURCE_DIR, ZIP_DIR); } private static void zipFolderStructure(String sourceFolder, String zipFolder){ // Creating a ZipOutputStream by wrapping a FileOutputStream try (FileOutputStream fos = new FileOutputStream(zipFolder); ZipOutputStream zos = new ZipOutputStream(fos)) { Path sourcePath = Paths.get(sourceFolder); // Walk the tree structure using WalkFileTree method Files.walkFileTree(sourcePath, new SimpleFileVisitor<Path>(){ @Override // Before visiting the directory create the directory in zip archive public FileVisitResult preVisitDirectory(final Path dir, final BasicFileAttributes attrs) throws IOException { // Don't create dir for root folder as it is already created with .zip name if(!sourcePath.equals(dir)){ System.out.println("Directory- " + dir); zos.putNextEntry(new ZipEntry(sourcePath.relativize(dir).toString() + "/")); zos.closeEntry(); } return FileVisitResult.CONTINUE; } @Override // For each visited file add it to zip entry public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException { System.out.println("File Name- " + sourcePath.relativize(file).toString()); zos.putNextEntry(new ZipEntry(sourcePath.relativize(file).toString())); Files.copy(file, zos); zos.closeEntry(); return FileVisitResult.CONTINUE; }}); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }Output
Directory- F:\knpcode\Parent\Child File Name- Child\hello.txt File Name- Child\Project.docx File Name- Test.txt
Zip a folder in Java by listing files recursively
In the code you first create a list of all the files and folders residing with in a parent folder. To go through the list of files with in a directory listFiles() method of java.io.File class is used.
Once you have this folder tree structure in a list you iterate through that list to create a zip archive. For every iterated element of the list you check if it is a directory or a file-
- If it is a directory then you just add the name of the directory in the zip archive.
- If it is a file then you add the name as well as the content of the file.
public class ZippingFolder { List fileList = new ArrayList(); public static void main(String[] args) { // Source folder final String ROOT_DIR = "F:/knpcode/Parent"; // creating the name of the zipped archive String ZIP_DIR = ROOT_DIR.concat(".zip"); ZippingFolder zippingFolder = new ZippingFolder(); // get the list of the whole folder structure zippingFolder.getListOfFiles(new File(ROOT_DIR)); zippingFolder.zipTreeStructure(ROOT_DIR, ZIP_DIR); } private void zipTreeStructure(String ROOT_DIR, String zipDir){ final int BUFFER = 1024; BufferedInputStream bis = null; ZipOutputStream zos = null; try{ // Creating ZipOutputStream by wrapping FileOutputStream FileOutputStream fos = new FileOutputStream(zipDir); zos = new ZipOutputStream(fos); // iterating the folder tree structure for(File file : fileList){ // If directory if(file.isDirectory()){ // add the directory name as zipentry ZipEntry ze = new ZipEntry(file.getName()+"/"); zos.putNextEntry(ze); zos.closeEntry(); } // If file else{ FileInputStream fis = new FileInputStream(file); bis = new BufferedInputStream(fis, BUFFER); ZipEntry ze = new ZipEntry(getFileName(ROOT_DIR, file.toString())); zos.putNextEntry(ze); byte data[] = new byte[BUFFER]; int count; while((count = bis.read(data, 0, BUFFER)) != -1) { zos.write(data, 0, count); } bis.close(); zos.closeEntry(); } } }catch(IOException ioExp){ ioExp.printStackTrace(); } finally{ try { zos.close(); if(bis != null) bis.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } // Method to get the folder tree structure private void getListOfFiles(File source){ File[] fileNames = source.listFiles(); for(File file : fileNames){ if(file.isDirectory()){ fileList.add(file); // recursive call to go through the subdirectory structure getListOfFiles(file); }else{ fileList.add(file); } } } // To get the relative file path private String getFileName(String ROOT_DIR, String filePath){ String name = filePath.substring(ROOT_DIR.length() + 1, filePath.length()); return name; } }
That's all for the topic How to Zip a Folder in Java. If something is missing or you have something to share about the topic please write a comment.
You may also like
- Creating Password Protected Zip File in Java
- GZIP File in Java – Compression And Decompression
- Write to Excel File in Java Using Apache POI
- Convert LocalDateTime to OffsetDateTime in Java
- Radix Sort Java Program
- ArrayBlockingQueue in Java With Examples
- Java String - substring() Method Example
- Spring Bean Definition Inheritance
- Input from User in Python – input() function
- React Example - Update Object in an Array of Objects
No comments:
Post a Comment