Unzip encrypted zip file using it's input stream in JAVA - java

Need a solution in Java to unzip a huge file(Won't fit in memory) using inputstream. File Object is not available in this case. The file is password protected. Solutions with File object won't help.
I've already tried with 7Zip, But it's not supporting the above case.

When you use streams, you should not read more data than requires. have you tried this?
public void unzip(InputStream is, Cipher cypher) throws IOException {
ZipInputStream zis = new ZipInputStream(new CipherInputStream(is,cypher));
ZipEntry zipEntry = zis.getNextEntry();
byte[] buffer = new byte[1024];
while (zipEntry != null) {
File newFile = new File(zipEntry.getName());
FileOutputStream fos = new FileOutputStream(newFile);
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.close();
zipEntry = zis.getNextEntry();
}
zis.closeEntry();
zis.close();
}

I had such problems too.
In this repo(https://github.com/r331/memzipenc) you can find a method MemZipDec.unzipFiles(byte[] zipBytes, String password)
I hope it would help.

Related

Java - moving items from a zip file into a password-protected zip file

Is there a way to use ZipOutputStream (from java.util.zip) with a password?
I'm working on copying files from a (unencrypted) zip file into another encrypted zipfile. Using ZipInpuStream/ZipOutputStream it is possible to read from the original zip file into the target zip file but I haven't seen a recipe that talks about how to use password on the ZipOutputStream.
ZipInputStream zis = new ZipInputStream(new FileInputStream(inputFile));
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(outputFile));
byte[] buff = new byte[1024];
while (true) {
int bytesRead = zis.read(buff, 0, 1024);
if (bytesRead < 0) {
// finished
break;
}
zos.write(buff, 0, bytesRead);
}
zos.flush();
zos.close();
zis.close();
I'm afraid it's difficult to set a password for Java.util.zip, Try to use zip4j https://github.com/srikanth-lingala/zip4j

Zip multipartfile and store via FTP

I take a multipartfile (i.e. SAMPLE.csv) in input.
I should zip it (i.e. SAMPLE.zip) and store it via FTP.
public void zipAndStore(MultipartFile file) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos);
InputStream is = file.getInputStream()) {
ZipEntry zipEntry = new ZipEntry("SAMPLE.zip");
zos.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while ((length = is.read(bytes)) >= 0) {
zos.write(bytes, 0, length);
}
zos.closeEntry();
storeFtp("SAMPLE.zip", new ByteArrayInputStream(baos.toByteArray()));
} catch (Exception e) {
}
}
The storeFtp use the org.apache.commons.net.ftp.FTPClient.storeFile(String remote, InputStream local) method.
The problem is that the uploaded file is corrupted and i'm unable to manually decompress.
What's wrong?
A zipfile has a list of DirEntries and a endLocator at the end of the file (after all the ZipFileRecords, i.e. the ZipEntries in the code).
So you probably have to close the zipfile before calling storeFtp() to make sure the DirEntries and the endLocator are written to the file:
zos.closeEntry();
zos.close();
storeFtp("SAMPLE.zip", new ByteArrayInputStream(baos.toByteArray()));
(I don't know Java that well, so I can't check or test the full code)
Also check out this answer.

'On the fly' unpackaging of files on Android

I need to package a few files (total upto 4 GB in size) which will be available online. An android app needs to download this 'on the fly' without saving the archive on to the device. So basically the device won't save the archive and then unpack, as it would require double the space. Which package format should I choose that will support it (eg. zip, tar.gz etc.)?
Use .zip! You can use ZipInputStream and ZipOutputStream to read and write from .zip files on the fly. No need to extract the files from the archive.
Link to documentation
And here is a quick example:
InputStream is =...
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(is));
try {
// ZipEntry contains data about files and folders in the archive.
ZipEntry ze;
// This loops through the whole content of the archive
while ((ze = zis.getNextEntry()) != null) {
// Here we read the whole data of one ZipEntry
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int count;
while ((count = zis.read(buffer)) != -1) {
baos.write(buffer, 0, count);
}
// The ZipEntry contains data about the file, like its filename
String filename = ze.getName();
// And that's the file itself as byte array
byte[] bytes = baos.toByteArray();
// Do something with the file
}
} finally {
zis.close();
}

making zip process more optimized one

I have developed a method to zip a file that will take file path and filename as a parameter and will zip a file as shown below could you please advise how can I modify this method to be more efficient and more fast as I am a big fan of optimization..
public File generateZipForAFile(String folderPath, String reportFileName)
throws FileNotFoundException, IOException {
File inputFile = new File(folderPath + reportFileName);
FileInputStream in = new FileInputStream(inputFile);
File outputZipFile = new File(folderPath, reportFileName + ".zip");
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(outputZipFile));
// Add ZIP entry to output stream.
out.putNextEntry(new ZipEntry(reportFileName ));
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.closeEntry();
out.close();
in.close();
return outputZipFile;
}
There is not much you can do in your code. Furthermore, most of the time is spent while actually doing the zip.
So even if you reduce the time spent in your part to 0 the overall gain will be very small.

Java copying a file out of a jar

I am trying to copy a file (Base.jar) to the same directory as the running jar file
I keep getting a corrupted jar file, that still holds the correct class structure when opened with winrar. What am I doing wrong? (I have also tried without the ZipInputStream, but that was no help) the byte[] is 20480 because that is size of it on the disk.
my code:
private static void getBaseFile() throws IOException
{
InputStream input = Resource.class.getResourceAsStream("Base.jar");
ZipInputStream zis = new ZipInputStream(input);
byte[] b = new byte[20480];
try {
zis.read(b);
} catch (IOException e) {
}
File dest = new File("Base.jar");
FileOutputStream fos = new FileOutputStream(dest);
fos.write(b);
fos.close();
input.close();
}
InputStream input = Resource.class.getResourceAsStream("Base.jar");
File fileOut = new File("your lib path");
OutputStream out = FileUtils.openOutputStream(fileOut);
IOUtils.copy(in, out);
in.close();
out.close();
and handle exceptions
No need to use ZipInputStream, unless you want to unzip the contents into memory and read.
Just use BufferedInputStream(InputStream) or BufferedReader(InputStreamReader(InputStream)).
did some more googling found this: (Convert InputStream to byte array in Java) worked for me
InputStream is = ...
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
while ((nRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
return buffer.toByteArray();
(it looks very simular to the src for IOUtils.copy())
ZipInputStream is for reading files in the ZIP file format by entry. You need to copy the whole file (resource) that is you need to simply copy all bytes from InputStream no matter what format is. The best way to do it in Java 7 is this:
Files.copy(inputStream, targetPath, optionalCopyOptions);
see API for details

Categories