Tuesday, November 7, 2017

Split ZIP in JAVA (limit ZIP size)

I am using below code/class to split and zip a large amount/size of files using JAVA.
I have tested this code/class on below

 - number of uncompressed files : 116
 - total size (uncompressed) : 29.1 GB
 - ZIP file size limit (each) : 3 GB [MAX_ZIP_SIZE]
 - total size (compressed)   : 7.85 GB
 - number of ZIP file (splited as MAX_ZIP_SIZE): 3

In my code, MAX_ZIP_SIZE set to 3 GB ([ZIP has limitation of 4GB on various things]).

you need to change MAX_ZIP_SIZE value as per your requirement ...

////////////////////////// JAVA Code \\\\\\\\\\\\\\\\\\\\\\\\
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipOutputStream;

    public class QDE_ZIP {

        public static String createZIP(String directoryPath, String zipFileName, String filesToZip) {
            try {
                final int BUFFER = 104857600; // 100MB
                final long MAX_ZIP_SIZE = 3221225472L; //3 GB
                long currentSize = 0;
                int zipSplitCount =0;
                String files[] = filesToZip.split(",");
                if (!directoryPath.endsWith("/")) {
                    directoryPath = directoryPath + "/";
                }
                byte fileRAW[] = new byte[BUFFER];
                ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(directoryPath + zipFileName.toUpperCase()));
                ZipEntry zipEntry;
                FileInputStream entryFile;
                for (String aFile : files) {
                    zipEntry = new ZipEntry(aFile);
                    if (currentSize >= MAX_ZIP_SIZE)
                    {
                        zipSplitCount ++;
                        zipOut.close();
                        zipOut = new ZipOutputStream(new FileOutputStream(directoryPath + zipFileName.toLowerCase().replace(".zip", "_"+zipSplitCount+".zip").toUpperCase()));
                        currentSize = 0;
                    }
                    zipOut.putNextEntry(zipEntry);
                    entryFile = new FileInputStream(directoryPath + aFile);

                    int count;
                    while ((count = entryFile.read(fileRAW, 0, BUFFER)) != -1) {
                        zipOut.write(fileRAW, 0, count);
                    }
                    entryFile.close();
                    zipOut.closeEntry();
                    currentSize += zipEntry.getCompressedSize();
                }
           
                zipOut.close();
                //System.out.println(directory + " -" + zipFileName + " -Number of Files = " + files.length);
            } catch (FileNotFoundException e) {
                return "FileNotFoundException = " + e.getMessage();
            } catch (IOException e) {
                return "IOException = " + e.getMessage();
            } catch (Exception e) {
                return "Exception = " + e.getMessage();
            }

            return "1";
        }

    }

////////////////////////// End JAVA Code \\\\\\\\\\\\\\\\\\\\\\\\

NOTE: I have returned all *Exception Messages* as String to work with it. this my own case related to project.


2 comments:

  1. If 'filesToZip' is only one file which is already bigger than MAX_ZIP_SIZE then your solution fails

    ReplyDelete
    Replies
    1. YES true;
      This solution try to fit full file within the MAX_ZIP_SIZE without breaking the original file.
      I will create the script which will break the original file to fit the MAX_ZIP_SIZE and let you know soon.

      Delete