Saving ZipOutputStream to zip file with Java - java

I have to create ZIP archive in memory
But now, I need it to be saved in a real .zip file in a disk. How to do it?
Pseudocode:
public byte[] crtZipByteArray(ByteArrayInputStream data,ZipEntry entry) throws IOException{
ByteArrayOutputStream zipout = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(zipout);
byte[] buffer = new byte[1024];
int len;
zos.putNextEntry(entry);
while ((len = data.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
zos.closeEntry();
zos.close();
data.close();
return zipout.toByteArray();
}

Replace ByteArrayOutputStream zipout with FileOutputStream zipout.
If you sill need to return byte array as method result use apache commons TeeOutputStream to duplicate output for two streams.
public byte[] crtZipByteArray(ByteArrayInputStream data,ZipEntry entry) throws IOException{
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
OutputStream fileOut = new FileOutputStream("filename.zip");
OutputStream teeOut = new TeeOutputStream(byteArrayOut, fileOut);
ZipOutputStream zos = new ZipOutputStream(teeOut);
.....
}

Related

Download zip file when call api

FileOutputStream fos = new FileOutputStream(FILE_NAME);
ZipOutputStream zipOut = new ZipOutputStream(fos);
for (File file : files) {
FileInputStream fis = new FileInputStream(file);
ZipEntry zipEntry = new ZipEntry(file.getName());
zipOut.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while((length = fis.read(bytes)) >= 0) {
zipOut.write(bytes, 0, length);
}
fis.close();
}
zipOut.close();
fos.close();
I have a zip file, I want to download it when I call the api.With the zip file, I don't know how to download. Hope to get help from you.
If you are using Spring/Spring Boot. You can follow this stackoverflow thread Download File in Spring

Set filename of an only streamed zip file

i am currently creating a zip file and filling it with various json files and images. All this should only run in memory and not on the hard disk. Therefore I have the following construct so far:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zip = null;
String FILE_NAME = "file.zip";
try {
zip = new ZipOutputStream(baos);
//now the critical part where the name of the file should be set
ZipEntry entry = new ZipEntry(FILE_NAME);
zip.putNextEntry(entry);
byte[] data = FILE_NAME.getBytes();
zip.write(data, 0, data.length);
zip.closeEntry();
//end of critical part and filling the rest of the zip
//...
//
}finally{
IOUtils.closeQuietly(zip);
byte[] byteFile = baos.toByteArray();
IOUtils.closeQuietly(baos);}
The problem is that the zip-file is called file.zip, but also contains a file.zip itself.
How can I name my Zip file from the ZipOutputStream without packing into this one file with the same name? Unfortunately I only found this solution here.
public byte[] zipBytesFile(List<byte[]> files) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos);
int i = 0;
for (byte[] file : files) {
ZipEntry entry = new ZipEntry(++i + ".pdf");
entry.setSize(file.length);
zos.putNextEntry(entry);
zos.write(file);
}
zos.closeEntry();
zos.close();
return baos.toByteArray();
}

java create NESTED zip recursively in memory

This is how I create a simple zip archive with 3 files
FileOutputStream fos = new FileOutputStream(new File("out.zip"));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zos = new ZipOutputStream(baos)) {
for (int i = 0; i < 3; i++) {
String s = "hello world " + i;
ZipEntry entry = new ZipEntry("text" + i + ".txt");
zos.putNextEntry(entry);
zos.write(s.getBytes());
zos.closeEntry();
}
}
baos.writeTo(fos);
How can I put a zip inside zip recursively in one turn on the fly? Is there any way to put ZipOutputStream or ZipEntry inside each other?
EDIT:
Solution as Mark suggested:
FileOutputStream fos = new FileOutputStream(new File("out.zip"));
ByteArrayOutputStream resultBytes = new ByteArrayOutputStream();
ByteArrayOutputStream zipOutStream = new ByteArrayOutputStream();
try (ZipOutputStream zos2 = new ZipOutputStream(zipOutStream)) {
String s = "hello world ";
ZipEntry entry = new ZipEntry("text.txt");
zos2.putNextEntry(entry);
zos2.write(s.getBytes());
zos2.closeEntry();
zos2.close();
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zos = new ZipOutputStream(baos)) {
ZipEntry entry = new ZipEntry("text.zip");
zos.putNextEntry(entry);
zos.write(zipOutStream.toByteArray());
zos.closeEntry();
}
baos.writeTo(resultBytes);
resultBytes.writeTo(fos);
I tried to follow the solution using the 'ByteArrayOutputStream' but only manage to create corrupted zip files this way.
I ended up creating a nested ZipOutputStream directly like this:
try (FileOutputStream fos = new FileOutputStream(myZipFile); ZipOutputStream zos = new ZipOutputStream(fos)) {
ZipEntry entry = new ZipEntry("inner.zip");
zos.putNextEntry(entry);
ZipOutputStream nestedZos = new ZipOutputStream(zos);
// write stuff to nestedZos
nestedZos.finish();
zos.closeEntry();
}
The resulting zip file contains the nested structure and is valid.
For the "inner" .ZIP file, you could use a ByteArrayOutputStream instead of a FileOutputStream; then that zip will be built as data in RAM; so you can use the resulting byte array as the data for a ZipEntry in the outer .ZIP file.

Zipping files with ZipOutputStream gives inconsistent results

I want to zip a text file using the java.util.ZipOutputStream class. I found two examples on the internet explaining on how to do that. This led me to the two possible implementations shown below. While both methods produce 'healthy zip files', my problem is that on every run the binary content of the file is slightly different (around the 10th byte). Does someone know if
This is intended behaviour
There is a way to always produce exactly the same result
Here is my current code:
public byte[] getZipByteArray(String fileName) throws IOException
{
byte[] result = new byte[0];
byte[] buffer = new byte[1024];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos);
ZipEntry ze = new ZipEntry(fileName);
zos.putNextEntry(ze);
InputStream inputStream = ZipCompression.class.getResourceAsStream(fileName);
int len;
while ((len = inputStream.read(buffer)) > 0)
{
zos.write(buffer, 0, len);
}
zos.closeEntry();
zos.close();
result = baos.toByteArray();
return result;
}
public byte[] ZipByteArrayBuffered(String fileName) throws IOException
{
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(byteArrayOutputStream);
ZipOutputStream zipOutputStream = new ZipOutputStream(bufferedOutputStream);
File file = new File(fileName);
InputStream fileInputStream = ZipCompression.class.getResourceAsStream(file.getName());
zipOutputStream.putNextEntry(new ZipEntry(file.getName()));
IOUtils.copy(fileInputStream, zipOutputStream);
fileInputStream.close();
zipOutputStream.closeEntry();
if (zipOutputStream != null)
{
zipOutputStream.finish();
zipOutputStream.flush();
IOUtils.closeQuietly(zipOutputStream);
}
IOUtils.closeQuietly(bufferedOutputStream);
IOUtils.closeQuietly(byteArrayOutputStream);
return byteArrayOutputStream.toByteArray();
}
Byte 10 starts the file modification date and so this will always differ. See Wikipedia for the details of the zip file format.

how to convert image to byte array in java?(With out using buffered image)

Hi could anyone please explain me how to convert the image data to byte array in java I am trying like this.I do not need to use buffered image here.
File file = new File("D:/img.jpg");
FileInputStream imageInFile = new FileInputStream(file);
byte imageData[] = new byte[(int) file.length()];
imageInFile.read(imageData);
You can convert your image data using FileInputStream also.
File file = new File("D:\\img.jpg");
FileInputStream fis = new FileInputStream(file);
//Now try to create FileInputStream which obtains input bytes from a file.
//FileInputStream is meant for reading streams of raw bytes,in this case its image data.
//For reading streams of characters, consider using FileReader.
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
try {
for (int readNum; (readNum = fis.read(buf)) != -1;) {
//Now Write to this byte array output stream
bos.write(buf, 0, readNum);
System.out.println("read " + readNum + " bytes,");
}
} catch (IOException ex) {
Logger.getLogger(ConvertImage.class.getName()).log(Level.SEVERE, null, ex);
}
byte[] bytes = bos.toByteArray();
or you could use:
Image image = Toolkit.getDefaultToolkit().getImage("D:/img.jpg");
byte[] imageBytes = getImageBytes(image);
private byte[] getImageBytes(Image image) throws IOException {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
ImageIO.write(image, "bmp", baos);
baos.flush();
return baos.toByteArray();
}
}

Categories

Resources