In this post we'll see how to zip a single file in Java and also how to zip files recursively in Java to compress a whole directory.
In Java, java.util.zippackage 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 a 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 code for zipping 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 {
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{
// Creating ZipOutputStream
FileOutputStream fos = new FileOutputStream("G:\\test.zip");
zos = new ZipOutputStream(fos);
FileInputStream fis = new FileInputStream("G:\\test.txt");
bis = new BufferedInputStream(fis, BUFFER);
// ZipEntry --- Here file name can be created using the source file
ZipEntry ze = new ZipEntry("test.txt");
// 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();
}
}
}
}
}
Zipping files in folders and subfolders recursively
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.
Java code to zip files recursively
Here is the Java code that goes through the folder structure and zips all files and sub-folders recursively. It will even take care of the empty folders in the source folder.
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;
}
}
Zipping files in folders and subfolders recursively in Java 7
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. 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();
}
}
}
That's all for this topic Zipping files in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!
Related Topics
You may also like -