i have a code that takes a file, zip it, and stores it in a database
looks like this
// STEP 1 - Create a ZIP file
byte[] buffer = new byte[1024];// 18024
ZipOutputStream outZip = new ZipOutputStream(new FileOutputStream("file.zip"));
outZip.setLevel(Deflater.DEFAULT_COMPRESSION);
FileInputStream in = new FileInputStream(c:\file.hex);
outZip.putNextEntry(new ZipEntry("file.hex"));
int len;
while (( len = in.read(buffer)) > 0)
outZip.write(buffer, 0, len);
outZip.closeEntry();
in.close();
outZip.close();
// STEP 2 - Insert zip file to DB
file = new File("file.zip");
FileInputStream fis = new FileInputStream( file );
the fis object i store in the DB
but i would like to avoid the filesystem completely , and not create the file.zip.
i think i need to convert the ZipOutputStream into FileInputStream directly
but i could not find a way to do it.
is there an easy way to accomplish this ?
i also have the same problem when i extract the file, in order to read it i must create 2 different temporary files - file.zip and file.hex
You just do not have to create FileOutputStream at all. Use ByteArrayOutputStream instead:
ByteArrayOutputStream zipBytes = new ByteArrayOutputStream()
ZipOutputStream outZip = new ZipOutputStream(zipBytes);
// run your code that adds zip entries....
zipBytes.getBytes() // returns array of bytes that contain your zipped information.
Related
The steps I followed are.
get all objects from recursive objects
Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder()
.bucket(bucketName).recursive(true).build());
Then getting all streams of matching the prefix
InputStream stream = minioClient.getObject(GetObjectArgs.builder()
.bucket(bucketName).object(objectName).build());
the list of multiple stream got by the InputStream stream How do we convert it into zip file ?
tried the following code but it's (zipOut) coming as null.
downloading empty zip, How do we fix this ?
ByteArrayOutputStream fos = new ByteArrayOutputStream();
ZipOutputStream zipOut = new ZipOutputStream(fos);
ZipEntry zipEntry1 = new ZipEntry(objectName);
zipEntry1.setSize(resource.contentLength());
zipEntry1.setTime(System.currentTimeMillis());
zipOut.putNextEntry(zipEntry1);
StreamUtils.copy(stream.readAllBytes(), zipOut);
zipOut.closeEntry();
Thanks in advance.
I converted a zip file of 5 files into a byte array. I want to output a zip file on my disk from that bytearray. My process was first reading the byte[] into a ByteArrayInputStream then into a ZipInputStream.
InputStream plainTextStream = new ByteArrayInputStream(plainText);
ZipInputStream zipInStream = new ZipInputStream(plainTextStream);
I want this to be outputted into a zip file on my disk so here I thought I will need a file and a ZipOutPutStream passing that zip file.
ZipOutputStream zipOutStream = new ZipOutputStream(new FileOutputStream(file));
With a zip entry I traversed the ZipInPutStream writing to a FileOutputStream each entry, using a buffer. At the end of each main loop I put an entry into the ZipOutPutStream.
ZipEntry entry = null;
while((entry = zipInStream.getNextEntry()) != null){
FileOutputStream fileOutStream = new FileOutputStream(entry.getName());
byte[] byteBuff = new byte[1024];
int bytesRead = 0;
while ((bytesRead = zipInStream.read(byteBuff)) != -1)
{
fileOutStream.write(byteBuff, 0, bytesRead);
}
fileOutStream.close();
zipOutStream.putNextEntry(entry);
zipInStream.closeEntry();
}
I add the first file from the zip (there are 5 files), but when trying to add the 2nd file, I get an error on
zipOutStream.putNextEntry(entry)
java.util.zip.ZipException: invalid entry size (expected 18401 but got 0 bytes)
Through debugging I can't figure out where it goes wrong. I assume it may have something to do with the buffer when putting in the first outputstream(entry.getName())? The bytesRead while loop could be an issue.
This is all assuming the logic makes sense. I hope I can approach a solution to this error.
You never write the content of the zipped files to the zip output stream.
You don't need to write the output to a file stream, just write it directly to the zip output stream.
You should be using try-with-resources.
try (ZipInputStream zipInStream = new ZipInputStream(new ByteArrayInputStream(plainText));
ZipOutputStream zipOutStream = new ZipOutputStream(new FileOutputStream(file));
) {
byte[] byteBuff = new byte[1024];
for (ZipEntry entry; (entry = zipInStream.getNextEntry()) != null; ) {
zipOutStream.putNextEntry(entry);
for (int bytesRead; (bytesRead = zipInStream.read(byteBuff)) != -1; ) {
zipOutStream.write(byteBuff, 0, bytesRead);
}
}
}
There is no need to call closeEntry().
To resolve (expected 18401 but got 0 bytes)
Create a new blank excel file.
Copy data from the file you copied from zip to the new created file in step 1.
Use the new file, it should work as its worked for me.
Thanks.
Follow up of Question: Java: how to compress a byte[] using ZipOutputStream without intermediate file
I can zip data without an intermediate file (or memory file). I now need to zip chunks of data and add them to a single zip file.
I am using a single ZipOutputStream as suggested in the previous question.
String infile = "test.txt";
FileInputStream in = new FileInputStream(infile);
String outfile = "test.txt.zip";
FileOutputStream out = new FileOutputStream(outfile);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos);
ZipEntry entry = new ZipEntry("test_unzip.txt");
entry.setSize(2048);
zos.putNextEntry(entry);
int len = 0;
while (len > -1) {
byte[] buf = new byte[10];
len = in.read(buf);
zos.write(buf);
out.write(baos.toByteArray());
baos.reset();
}
zos.closeEntry();
zos.finish();
zos.close();
in.close();
out.close();
I have tried different sizes for buf, reordering zos.finish and zos.closeEntry, and also tried with and without baos.reset.
I have also tried reading the entire contents of infile into a single buf but still not working.
I expected a valid .zip file that will unzip into test_unzip.txt.
However, when i try unzip test.txt.zip on my command line i get the following error:
End-of-central-directory signature not found. Either this file is not
a zipfile, or it constitutes one disk of a multi-part archive. In the latter case the central directory and zipfile comment will be found on the last disk(s) of this archive.
unzip: cannot find zipfile directory in one of test.txt.zip or
test.txt.zip.zip, and cannot find test.txt.zip.ZIP, period.
I have a chararray which holds coordinates in every index. I want to compress the array with zip algorithm and write the zipped version of the array to a file. My idea was that i run the chararray through a zip stream and write it afterwards directly to a file like test.txt. The problem is, that nothing is written to the file after the execution of the code. Can somebody please help me solve that problem?
Kind regards Lorenzo
Here my current code:
byte[] bytes = Charset.forName("UTF-8").encode(CharBuffer.wrap(sample)).array();
FileOutputStream out = new FileOutputStream(cscFile, true);
byte[] compressed = new byte[bytes.length];
ByteArrayInputStream bi = new ByteArrayInputStream(bytes);
ZipInputStream zi = new ZipInputStream(bi);
ZipEntry entry = null;
while ((entry = zi.getNextEntry()) != null) {
zi.read(compressed);
for(int i = 0; i<bytes.length;i++){
out.write(compressed[i]);
}
out.flush();
out.close();
zi.closeEntry();
}
zi.close();
You will probably have to slightly modify your code with something like this:
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(new File("your zip file name")));
ZipEntry entry = new ZipEntry("zipped file name");
entry.setSize(bytes.length);
zos.putNextEntry(entry);
zos.write(bytes);
zos.closeEntry();
zos.close();
Explanation:
To compress writen data, use ZipOutputStream and give created FileOutputStream as constructor argument. After that, create ZipEntry, which represents file inside your zip file and write contents of byte array into it.
Hope it helps.
See similar question here: https://stackoverflow.com/a/357892/3115098
I am trying to read multiple files (can be of any format i.e. pdf, txt, tiff etc) from URLs and zipping them using ZipOutputStream. My code looks like this:
// using in-memory file read
// then zipping all these files in-memory
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos);
.....
URL url = new URL(downloadUrl); // can be multiple URLs
ByteArrayOutputStream bais = new ByteArrayOutputStream();
InputStream is = url.openStream();
byte[] byteChunk = new byte[4096];
int n;
while ( (n = is.read(byteChunk)) > 0 )
{
bais.write(byteChunk, 0, n);
}
byte[] fileBytes = bais.toByteArray();
ZipEntry entry = new ZipEntry(fileName);
entry.setSize(fileBytes.length);
zos.putNextEntry(entry);
zos.write(fileBytes);
zos.closeEntry();
// close the url input stream
is.close();
// close the zip output stream
zos.close();
// read the byte array from ByteArrayOutputStream
byte[] zipFileBytes = baos.toByteArray();
String fileContent = new String(zipFileBytes);
I am then passing this content "fileContent" to my perl frontend application.
And I m using perl code to download this zipped file:
WPHTTPResponse::setHeader( 'Content-disposition', 'attachment; filename="test.zip"' );
WPHTTPResponse::setHeader( 'Content-type', 'application/zip');
print $result; // string coming from java application
But the zip file it is giving is corrupted. I think something in going wrong with the data translation.
I'd appreciate any help.
Your problem is thinking that you can output your zip bytes into a string. This string can not be used to reproduce the zip content again. You need to either use the raw bytes or encode the bytes into something that can be represented as a string, such as base64 encoding.