Reputation: 41
I am tasked with using open source 'zip4jlibrary for creating and unzipping of password-protected zip files. Method parameters will be
byte[]of file content and password and it should return a byte array as output (unzipped or zipped content), no
File system` involved. I tried the below code segment which throws
'net.lingala.zip4j.exception.ZipException: File does not exist: \test\Test.txt' at line "zipFile.addFiles(filesToAdd, zipParameters);" What I am missing here?
Exception in thread "main" net.lingala.zip4j.exception.ZipException: File does not exist: \test\ZipThis.txt
at net.lingala.zip4j.util.FileUtils.assertFileExists(FileUtils.java:526)
at net.lingala.zip4j.util.FileUtils.assertFilesExist(FileUtils.java:359)
at net.lingala.zip4j.tasks.AbstractAddFileToZipTask.addFilesToZip(AbstractAddFileToZipTask.java:62)
at net.lingala.zip4j.tasks.AddFilesToZipTask.executeTask(AddFilesToZipTask.java:27)
at net.lingala.zip4j.tasks.AddFilesToZipTask.executeTask(AddFilesToZipTask.java:15)
at net.lingala.zip4j.tasks.AsyncZipTask.performTaskWithErrorHandling(AsyncZipTask.java:51)
at net.lingala.zip4j.tasks.AsyncZipTask.execute(AsyncZipTask.java:45)
at net.lingala.zip4j.ZipFile.addFiles(ZipFile.java:318)
at net.lingala.zip4j.ZipFile.addFile(ZipFile.java:275)
public class ExtractZip {
public static byte[] extractWithZipInputStream(byte[] inputArr, char[] password) {
LocalFileHeader localFileHeader;
int readLen;
InputStream byteStream = new ByteArrayInputStream(inputArr);
byte[] readBuffer = new byte[4096];
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ZipInputStream zipInputStream = new ZipInputStream(byteStream, password);
try {
while ((localFileHeader = zipInputStream.getNextEntry()) != null) {
while ((readLen = zipInputStream.read(readBuffer)) != -1) {
bos.write(readBuffer, 0, readLen);
}
break;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bos.close();
} catch (Exception e) {
}
try {
zipInputStream.close();
} catch (Exception e) {
}
}
return bos.toByteArray();
}
public static void main(String[] args) {
FileOutputStream fos;
byte[] inputBuffer = new byte[1024];
try {
ZipParameters zipParameters = new ZipParameters();
zipParameters.setEncryptFiles(true);
zipParameters.setEncryptionMethod(EncryptionMethod.ZIP_STANDARD);
List<File> filesToAdd = Arrays.asList(new File("/test/ZipThis.txt"));
ZipFile zipFile = new ZipFile("/test/Template_Zip.zip", "abc123".toCharArray());
zipFile.addFiles(filesToAdd, zipParameters);
inputBuffer = Files.readAllBytes(Paths.get("/test/Template_Zip.zip"));
byte[] outputArr = ExtractZip.extractWithZipInputStream(inputBuffer, "abc123".toCharArray());
//Test if you can create a file using with this byte array
File unZipped = new File("/test/unzipped/temp");
fos = new FileOutputStream(unZipped);
fos.write(outputArr[0]);
fos.flush();
fos.close();
zipFile.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Upvotes: 0
Views: 2078
Reputation: 18255
Looks good to me. Just try to set absolute path
instead of the relative ones. E.g.
ZipFile zipFile = new ZipFile("c:/test/Template_Zip.zip", "abc123".toCharArray());
All other such places as well. I think your problem will go away.
P.S. It's better to use try with resources
instead of what you do.
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.io.inputstream.ZipInputStream;
import net.lingala.zip4j.model.LocalFileHeader;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.EncryptionMethod;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
public class ExtractZip {
public static byte[] extractWithZipInputStream(byte[] buf, char[] password) throws IOException {
try (InputStream byteStream = new ByteArrayInputStream(buf);
ZipInputStream zipInputStream = new ZipInputStream(byteStream, password);
ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
LocalFileHeader localFileHeader = zipInputStream.getNextEntry();
if (localFileHeader == null)
return new byte[0];
int readLen;
byte[] readBuffer = new byte[4096];
while ((readLen = zipInputStream.read(readBuffer)) != -1) {
bos.write(readBuffer, 0, readLen);
}
return bos.toByteArray();
}
}
public static void main(String[] args) throws IOException {
ZipParameters zipParameters = new ZipParameters();
zipParameters.setEncryptFiles(true);
zipParameters.setEncryptionMethod(EncryptionMethod.ZIP_STANDARD);
List<File> filesToAdd = Arrays.asList(new File("e:/foo.txt"));
ZipFile zipFile = new ZipFile("e:/Template_Zip.zip", "abc123".toCharArray());
zipFile.addFiles(filesToAdd, zipParameters);
byte[] buf = Files.readAllBytes(Paths.get("e:/Template_Zip.zip"));
buf = extractWithZipInputStream(buf, "abc123".toCharArray());
try (FileOutputStream fos = new FileOutputStream(new File("e:/fooZip.txt"))) {
fos.write(buf);
}
}
}
(advertisement) Try another library - zip4jvm. You can find it a bit easier to use.
Upvotes: 0