Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to create java zip archives with a max file size limit

Tags:

java

zip

I need to write an algorithm in java (for an android app) to read a folder containing more folders and each of those containing images and audio files so the structure is this: mainDir/categorySubfolder/myFile1.jpg

My problem is that I need to limit the size of the archive to 16mb and at runtime, create as many archives as needed to contain all my files from my main mainDir folder.

I tried several examples from the net and I read the java documentation but I can't manage to understand and put it all together the way I need it. Has someone done this before or has a link or an example for me?

I resolved the reading of the files with a recursive method but I can't write the logic for the zip creation.

I'm open for suggestions or better a working example.

like image 356
androidu Avatar asked Oct 22 '25 18:10

androidu


2 Answers

zip4j is a great library that can create multi-part zip files.

net.lingala.zip4j.core.ZipFile zipFile = new ZipFile("out.zip");
ZipParameters parameters = new ZipParameters();
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
zipFile.createZipFileFromFolder("path/to/source/dir", parameters, true, maximum size);

You can find more examples on their web-site.

like image 155
Arash Avatar answered Oct 24 '25 08:10

Arash


I am using below code/class to split and zip a large amount/size of files. I have tested this 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

you have to change the value of MAX_ZIP_SIZE to 16(MB)10241024=16777216-22(zip header size)=16777194.
In my code, MAX_ZIP_SIZE set to 3 GB (ZIP has limitation of 4GB on various things).

final long MAX_ZIP_SIZE = 3221225472L; //3 GB

package com.company;

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 QdeZip {

    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.closeEntry();
                    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);

                    //System.out.println("number of Bytes read = " + 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";
    }
}

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

like image 42
Azam Avatar answered Oct 24 '25 09:10

Azam



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!