How can I create a zip file without saving to disk with Java?

I created many BufferedImages in memory and I want to compress them into a single zip file before sending it as an email attachment. How to save files to zip without reading files from disk.

Is there a way to compress these files without creating a temporary file?

Burning to disk takes a long time due to the creation of thousands of files.

/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package cccprog; import java.awt.Component; import java.awt.Panel; import java.awt.event.KeyEvent; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JRadioButton; /** * * @author Z */ public class N { public static void main(String[] args) throws Exception { for (int i = 0; i < 10; i++) { JFrame jf = new JFrame(); Panel a = new Panel(); JRadioButton birdButton = new JRadioButton(); birdButton.setSize(100, 100); birdButton.setSelected(true); jf.add(birdButton); getSaveSnapShot(birdButton, i + ".bmp"); } } public static BufferedImage getScreenShot(Component component) { BufferedImage image = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TYPE_BYTE_GRAY); // paints into image Graphics component.paint(image.getGraphics()); return image; } public static void getSaveSnapShot(Component component, String fileName) throws Exception { BufferedImage img = getScreenShot(component); // BufferedImage img = new BufferedImage(image.getWidth(),image.getHeight(),BufferedImage.TYPE_BYTE_BINARY); // write the captured image as a bmp ImageIO.write(img, "bmp", new File(fileName)); } } 
+6
source share
2 answers

I'm not sure if you have a precedent, if you have thousands of files in memory, you can quickly lose memory.

However, zip files are usually generated by streams anyway, so there is no need to temporarily store them in a file - it can also be in memory or transferred directly to a remote recipient (with a small memory buffer to avoid a large amount of memory).

I found an old zip utility written several years ago and modified it a bit for your use case. It creates a zip file stored in a byte array from a list of files also stored in byte arrays. Since you have many files represented in memory, I added a small helper class, MemoryFile with just the file name and an array of bytes containing the contents. Oh, and I made the fields public to avoid working with templates / collectors - just to save space here, of course.

 public class MyZip { public static class MemoryFile { public String fileName; public byte[] contents; } public byte[] createZipByteArray(List<MemoryFile> memoryFiles) throws IOException { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream); try { for (MemoryFile memoryFile : memoryFiles) { ZipEntry zipEntry = new ZipEntry(memoryFile.fileName); zipOutputStream.putNextEntry(zipEntry); zipOutputStream.write(memoryFile.contents); zipOutputStream.closeEntry(); } } finally { zipOutputStream.close(); } return byteArrayOutputStream.toByteArray(); } } 
+9
source
  FileInputStream[] ins = //I assume you have all file handles in the form of FileInputStream String[] fileNames = //I assume you have all file names FileOutputStream out = new FileOutputStream(""); //specify the zip file name here ZipOutputStream zipOut = new ZipOutputStream(out); for (int i=0; i<ins.length; i++) { ZipEntry entry = new ZipEntry(fileNames[i]); zipOut.putNextEntry(entry); int number = 0; byte[] buffer = new byte[512]; while ((number = ins[i].read(buffer)) != -1) { zipOut.write(buffer, 0, number); } ins[i].close(); } out.close(); zipOut.close(); 

Based on the information you provided, I came up with the code above. Hope this helps.

+1
source

Source: https://habr.com/ru/post/952368/


All Articles