In this post we'll see how to zip files in Java and also how to zip a directory in Java where files and sub-directories are compressed recursively.
In Java, java.util.zip package provides classes for data compression and decompression. For compressing data to a ZIP file ZipOutputStream class can be used. The ZipOutputStream writes data to an output stream in zip format.
Steps to zip a file in Java
- First you need to create a ZipOutputStream object, to which you pass the output stream of the file you wish to use as a zip file.
- Then you also need to create an InputStream for reading the source file.
- Create a ZipEntry for file that is read.
ZipEntry entry = new ZipEntry(FILENAME)
Put the zip entry object using the putNextEntry method of ZipOutputStream - That's it now you have a connection between your InputStream and OutputStream. Now read data from the source file and write it to the ZIP file.
- Finally close the streams.
Java Program to zip a single file
import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ZipFileDemo { static final int BUFFER = 1024; public static void main(String[] args) { zipFile(); } // Method to zip file private static void zipFile(){ ZipOutputStream zos = null; BufferedInputStream bis = null; try{ // source file String fileName = "G:\\abc.txt"; File file = new File(fileName); FileInputStream fis = new FileInputStream(file); bis = new BufferedInputStream(fis, BUFFER); // Creating ZipOutputStream FileOutputStream fos = new FileOutputStream("G:\\abc.zip"); zos = new ZipOutputStream(fos); // ZipEntry --- Here file name can be created using the source file ZipEntry ze = new ZipEntry(file.getName()); // Putting zipentry in zipoutputstream 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 ioExp){ System.out.println("Error while zipping " + ioExp.getMessage()); }finally{ if(zos != null){ try { zos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(bis != null){ try { bis.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
Java Program to zip multiple files
In this Java example multiple files are zipped in Java using ZipOutputStream. Each source file is added as a ZipEntry to the ZipOutputStream.
public class ZipFileDemo { public static void main(String[] args) { try { //Source files String file1 = "G:/abc.txt"; String file2 = "G:/Test/abn.txt"; //Zipped file String zipFilename = "G:/final.zip"; File zipFile = new File(zipFilename); FileOutputStream fos = new FileOutputStream(zipFile); ZipOutputStream zos = new ZipOutputStream(fos); zipFile(file1, zos); zipFile(file2, zos); zos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // Method to zip file private static void zipFile(String fileName, ZipOutputStream zos) throws IOException{ final int BUFFER = 1024; BufferedInputStream bis = null; try{ File file = new File(fileName); FileInputStream fis = new FileInputStream(file); bis = new BufferedInputStream(fis, BUFFER); // ZipEntry --- Here file name can be created using the source file ZipEntry zipEntry = new ZipEntry(file.getName()); zos.putNextEntry(zipEntry); byte data[] = new byte[BUFFER]; int count; while((count = bis.read(data, 0, BUFFER)) != -1) { zos.write(data, 0, count); } // close entry every time zos.closeEntry(); } finally{ try { bis.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
Zipping Directory recursively in Java
If you have a folder structure as given below and you want to zip all the files in the parent folder and its sub folders recursively, then you need to go through the list of files and folders and compress them.
For zipping directory in Java two approaches are given here.
- You can use Files.walkFileTree() method (Java 7 onward) which recursively visit all the files in a file tree.
- You can read files in the folder with in the code and add them to a list and then compress the files with in that list.
Zipping Directory recursively in Java Using Files.walkFileTree()
If you are using Java 7 or higher then you can use Path and Files.walkFileTree() method to recursively zip the files. Using Files.walkFileTree() method makes the code shorter and leaves most of the work to API.
You need to implement FileVisitor interface which is one of the argument of the walkFileTree() method, implementation of two of the methods of FileVisitor is required-
preVisitDirectory- For directories you just need to make entry of the directory path.
visitFile- Zip each visited file.
Here try-with-resources in Java 7 is also used for managing resources automatically.
import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ZipFolderSeven { // Source folder which has to be zipped static final String FOLDER = "G:\\files"; public static void main(String[] args) { ZipFolderSeven zs = new ZipFolderSeven(); zs.zippingInSeven(); } private void zippingInSeven(){ // try with resources - creating outputstream and ZipOutputSttream try (FileOutputStream fos = new FileOutputStream(FOLDER.concat(".zip")); ZipOutputStream zos = new ZipOutputStream(fos)) { Path sourcePath = Paths.get(FOLDER); // using WalkFileTree to traverse directory Files.walkFileTree(sourcePath, new SimpleFileVisitor<Path>(){ @Override public FileVisitResult preVisitDirectory(final Path dir, final BasicFileAttributes attrs) throws IOException { // it starts with the source folder so skipping that if(!sourcePath.equals(dir)){ //System.out.println("DIR " + dir); zos.putNextEntry(new ZipEntry(sourcePath.relativize(dir).toString() + "/")); zos.closeEntry(); } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException { 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(); } } }
Java code to zip files recursively using list() method
Here is the Java code that goes through the folder structure and zips all files and subfolders recursively. It will even take care of the empty folders in the source folder. In this example list() method of the File class is used.
- list()- Returns an array of strings naming the files and directories in the directory denoted by this abstract pathname.
import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ZipFolderDemo { static final int BUFFER = 1024; // Source folder which has to be zipped static final String FOLDER = "G:\\files"; List<File> fileList = new ArrayList<File>(); public static void main(String[] args) { ZipFolderDemo zf = new ZipFolderDemo(); // get list of files List<File> fileList = zf.getFileList(new File(FOLDER)); //go through the list of files and zip them zf.zipFiles(fileList); } private void zipFiles(List<File> fileList){ try{ // Creating ZipOutputStream - Using input name to create output name FileOutputStream fos = new FileOutputStream(FOLDER.concat(".zip")); ZipOutputStream zos = new ZipOutputStream(fos); // looping through all the files for(File file : fileList){ // To handle empty directory if(file.isDirectory()){ // ZipEntry --- Here file name can be created using the source file ZipEntry ze = new ZipEntry(getFileName(file.toString())+"/"); // Putting zipentry in zipoutputstream zos.putNextEntry(ze); zos.closeEntry(); }else{ FileInputStream fis = new FileInputStream(file); BufferedInputStream bis = new BufferedInputStream(fis, BUFFER); // ZipEntry --- Here file name can be created using the source file ZipEntry ze = new ZipEntry(getFileName(file.toString())); // Putting zipentry in zipoutputstream 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(); } } zos.close(); }catch(IOException ioExp){ System.out.println("Error while zipping " + ioExp.getMessage()); ioExp.printStackTrace(); } } /** * This method will give the list of the files * in folder and subfolders * @param source * @return */ private List<File> getFileList(File source){ if(source.isFile()){ fileList.add(source); }else if(source.isDirectory()){ String[] subList = source.list(); // This condition checks for empty directory if(subList.length == 0){ //System.out.println("path -- " + source.getAbsolutePath()); fileList.add(new File(source.getAbsolutePath())); } for(String child : subList){ getFileList(new File(source, child)); } } return fileList; } /** * * @param filePath * @return */ private String getFileName(String filePath){ String name = filePath.substring(FOLDER.length() + 1, filePath.length()); //System.out.println(" name " + name); return name; } }
That's all for this topic Zipping Files And Folders in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!
>>>Return to Java Programs Page
Related Topics
You may also like-