Tuesday, 28 June 2016

Zipping files in Java

In Java java.util.zip package provides classes for data compression and decompression. For compressing data to a ZIP file ZipOutputStream can be used.The ZipOutputStream writes data to an output stream in a ZIP format.

Steps for Zipping data to a file

  • First you need to create a ZipOutputStream object, to which we pass the output stream of the file we wish to write to.
  • 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 sinlge 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) {
        try{
            // Creating ZipOutputStream
            FileOutputStream fos = new FileOutputStream("G:\\test.zip");
            ZipOutputStream zos = new ZipOutputStream(fos);
            
            
            FileInputStream fis = new FileInputStream("G:\\test.txt");
            BufferedInputStream 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);
            }
            
            zos.close();
            bis.close();
        }catch(IOException ioExp){
            System.out.println("Error while zipping " + ioExp.getMessage());
        }
    }
}
 

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. Then you need to go through the list of files and folders and compress them.

zipping files in Java

Java Code

Here is the Java code that go through the folder structure and zips all files and subfolders 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 make the code shorter and leave 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

  1. Unzipping files in Java
  2. How to convert a file to byte array
  3. Reading file in Java using BufferedReader
  4. How to read file from the last line in Java
  5. Reading file in Java using Scanner

You may also like -

>>>Go to Java Programs page

No comments:

Post a Comment