Skip to content

Commit

Permalink
#497 Create split zip file from stream
Browse files Browse the repository at this point in the history
  • Loading branch information
srikanth-lingala committed Mar 29, 2023
1 parent 62e7868 commit c4c993c
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 3 deletions.
34 changes: 32 additions & 2 deletions src/main/java/net/lingala/zip4j/ZipFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ public ZipFile(File zipFile, char[] password) {
* @param parameters - zip parameters for this file list
* @param splitArchive - if archive has to be split or not
* @param splitLength - if archive has to be split, then length in bytes at which it has to be split
* @throws ZipException
* @throws ZipException - if zip file already exists, or of split length is less than 65536
*/
public void createSplitZipFile(List<File> filesToAdd, ZipParameters parameters, boolean splitArchive,
long splitLength) throws ZipException {
Expand All @@ -180,12 +180,42 @@ public void createSplitZipFile(List<File> filesToAdd, ZipParameters parameters,

createNewZipModel();
zipModel.setSplitArchive(splitArchive);
zipModel.setSplitLength(splitLength);
zipModel.setSplitLength(splitArchive ? splitLength : -1);

new AddFilesToZipTask(zipModel, password, headerWriter, buildAsyncParameters()).execute(
new AddFilesToZipTaskParameters(filesToAdd, parameters, buildConfig()));
}

/**
* Creates a split zip file from the input stream if splitArchive flag is set to true. If this flag is set to false
* this method behaves as creating a regular (non-split) zip file. Split Length has to be more than 65536 bytes
*
* @param inputStream stream to add to the zip file
* @param parameters zip parameters to consider when creating the zip file
* @param splitArchive true if zip file has to be split, false otherwise
* @param splitLength length in bytes at which the zip file has to be split
* @throws ZipException if zip file already exists, or of split length is less than 65536
*/
public void createSplitZipFile(InputStream inputStream, ZipParameters parameters, boolean splitArchive,
long splitLength) throws ZipException {

if (zipFile.exists()) {
throw new ZipException("zip file: " + zipFile
+ " already exists. To add files to existing zip file use addFile method");
}

if (inputStream == null) {
throw new ZipException("input stream is null, cannot create zip file");
}

createNewZipModel();
zipModel.setSplitArchive(splitArchive);
zipModel.setSplitLength(splitArchive ? splitLength : -1);

new AddStreamToZipTask(zipModel, password, headerWriter, buildAsyncParameters()).execute(
new AddStreamToZipTaskParameters(inputStream, parameters, buildConfig()));
}

/**
* Creates a zip file and adds the files/folders from the specified folder to the zip file.
* This method does the same functionality as in addFolder method except that this method
Expand Down
64 changes: 64 additions & 0 deletions src/test/java/net/lingala/zip4j/CreateZipFileIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import net.lingala.zip4j.model.enums.CompressionLevel;
import net.lingala.zip4j.model.enums.CompressionMethod;
import net.lingala.zip4j.model.enums.EncryptionMethod;
import net.lingala.zip4j.testutils.TestUtils;
import net.lingala.zip4j.testutils.ZipFileVerifier;
import net.lingala.zip4j.util.FileUtils;
import net.lingala.zip4j.util.InternalZipConstants;
Expand All @@ -19,6 +20,9 @@
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

Expand Down Expand Up @@ -281,6 +285,66 @@ public void testCreateZipFileWithDeflateNoCompressionLevel() throws IOException
verifyZipFileByExtractingAllFiles(generatedZipFile, outputFolder, 3);
}

@Test
public void testCreateZipFileFromStreamThrowsExceptionIfZipFileExists() throws IOException {
try (ZipFile zipFile = new ZipFile(generatedZipFile)) {
zipFile.addFile(TestUtils.getTestFileFromResources("sample.pdf"));
}

expectedException.expect(ZipException.class);
expectedException.expectMessage("zip file: " + generatedZipFile
+ " already exists. To add files to existing zip file use addFile method");

try (ZipFile zipFile = new ZipFile(generatedZipFile)) {
zipFile.createSplitZipFile((InputStream) null, new ZipParameters(), true, 512000);
}
}

@Test
public void testCreateZipFileFromStreamCreatesSplitFileSuccessfully() throws IOException {
Path fileToAdd = TestUtils.getTestFileFromResources("file_PDF_1MB.pdf").toPath();
ZipParameters zipParameters = new ZipParameters();
zipParameters.setFileNameInZip(fileToAdd.getFileName().toString());

try (ZipFile zipFile = new ZipFile(generatedZipFile);
InputStream inputStream = Files.newInputStream(fileToAdd)) {
zipFile.createSplitZipFile(inputStream, zipParameters, true, 512000);
}

verifyZipFileByExtractingAllFiles(generatedZipFile, null, outputFolder, 1);
verifySplitZip(generatedZipFile, 2, 512000);
}

@Test
public void testCreateZipFileFromStreamCreatesNonSplitFileWhenFlagIsFalse() throws IOException {
Path fileToAdd = TestUtils.getTestFileFromResources("file_PDF_1MB.pdf").toPath();
ZipParameters zipParameters = new ZipParameters();
zipParameters.setFileNameInZip(fileToAdd.getFileName().toString());

try (ZipFile zipFile = new ZipFile(generatedZipFile);
InputStream inputStream = Files.newInputStream(fileToAdd)) {
zipFile.createSplitZipFile(inputStream, zipParameters, false, 512000);
}

verifyZipFileByExtractingAllFiles(generatedZipFile, null, outputFolder, 1);
verifySplitZip(generatedZipFile, 1, 512000);
}

@Test
public void testCreateZipFileFromStreamCreatesNonSplitFileWhenSplitLengthIsLowerThanFileLength() throws IOException {
Path fileToAdd = TestUtils.getTestFileFromResources("sample.pdf").toPath();
ZipParameters zipParameters = new ZipParameters();
zipParameters.setFileNameInZip(fileToAdd.getFileName().toString());

try (ZipFile zipFile = new ZipFile(generatedZipFile);
InputStream inputStream = Files.newInputStream(fileToAdd)) {
zipFile.createSplitZipFile(inputStream, zipParameters, true, 512000);
}

verifyZipFileByExtractingAllFiles(generatedZipFile, null, outputFolder, 1);
verifySplitZip(generatedZipFile, 1, 512000);
}

private void verifySplitZip(File zipFile, int numberOfExpectedSplitFiles, long splitLength) throws ZipException {
assertNumberOfSplitFile(zipFile, numberOfExpectedSplitFiles);
assertSplitFileSizes(zipFile, numberOfExpectedSplitFiles, splitLength);
Expand Down
12 changes: 11 additions & 1 deletion src/test/java/net/lingala/zip4j/ZipFileTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.List;

import static net.lingala.zip4j.util.InternalZipConstants.MIN_BUFF_SIZE;
import static org.assertj.core.api.Assertions.assertThat;
Expand Down Expand Up @@ -68,7 +70,7 @@ public void testCreateZipFileThrowsExceptionWhenFileListIsNull() throws ZipExcep
expectedException.expect(ZipException.class);
expectedException.expectMessage("input file List is null, cannot create zip file");

zipFile.createSplitZipFile(null, new ZipParameters(), true, 10000);
zipFile.createSplitZipFile((List<File>) null, new ZipParameters(), true, 10000);
}

@Test
Expand All @@ -79,6 +81,14 @@ public void testCreateZipFileThrowsExceptionWhenFileListIsEmpty() throws ZipExce
zipFile.createSplitZipFile(Collections.<File>emptyList(), new ZipParameters(), true, 10000);
}

@Test
public void testCreateZipFileFromStreamThrowsExceptionIfStreamIsNull() throws IOException {
expectedException.expect(ZipException.class);
expectedException.expectMessage("input stream is null, cannot create zip file");

zipFile.createSplitZipFile((InputStream) null, new ZipParameters(), true, 512000);
}

@Test
public void testCreateZipFileFromFolderThrowsExceptionWheFolderIsNull() throws ZipException {
expectedException.expect(ZipException.class);
Expand Down

0 comments on commit c4c993c

Please sign in to comment.