2013-08-23 10 views
6

Ho generato molte BufferedImages in memoria e voglio comprimerle in un unico file zip prima di inviarlo come allegato di posta elettronica. Come salvare i file in un file zip senza leggere i file dal disco.Come posso generare file zip senza salvare sul disco con Java?

C'è un modo per comprimere quei file senza creare un file temporaneo?

La scrittura su disco richiede molto tempo a causa della creazione di migliaia di file.

/* 
* 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's 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)); 
    } 
} 
+3

Vedere java.utli.zip. –

+1

Solo per la mia curiosità, perché vuoi evitare di creare un file temporaneo? –

+0

Questo sembra correlato http://stackoverflow.com/questions/7108035/how-to-flush-the-zipoutputstream-periodically-in-java – Ted

risposta

9

non sono sicuro circa l'uso caso hai qui, se si dispone di migliaia di file in memoria si potrebbe a corto di memoria piuttosto rapidamente.

Tuttavia, i file zip in genere vengono generati con flussi, quindi non è necessario memorizzarli temporaneamente in un file - potrebbero anche essere in memoria o trasmessi direttamente a un destinatario remoto (con solo un piccolo buffer di memoria per evitare un ingombro di memoria di grandi dimensioni).

Ho trovato una vecchia utilità zip scritta anni fa e leggermente modificata per la tua custodia. Crea un file zip memorizzato in un array di byte da un elenco di file, anch'esso memorizzato in array di byte. Dato che hai molti file rappresentati in memoria, ho aggiunto una piccola classe helper MemoryFile con solo il nome file e una matrice di byte contenente i contenuti. Oh, e ho reso i campi pubblici per evitare il roba di getter/setter di boilerplate - solo per risparmiare spazio qui, naturalmente.

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(); 
    } 

} 
+0

Ho aggiornato il mio post originale. Ero confuso su come utilizzare BufferImage per fare lo stesso. – user1198289

+0

Non hai solo "aggiornato" il tuo post originale, lo hai completamente cambiato. Non sono troppo affezionato a questo; cioè che la domanda è totalmente cambiata dopo aver passato del tempo a rispondere. Dovresti sapere che avere "migliaia" di PDF in memoria e migliaia di BufferedImages sono due cose diverse. Per ogni immagine, è necessario ottenere un flusso di output nel formato (gif, png, jpg, ecc.) Che si desidera salvare/trasferire in. Si noti inoltre che le immagini zippate hanno scarso effetto in termini di compressione, poiché di solito sono già compressi. – Steinar

1
   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(); 

Sulla base delle informazioni che ci ha fornito, vengo con il codice di cui sopra. Spero che questo ti aiuti.

+0

Ho aggiornato il mio post originale. Ero confuso su come utilizzare BufferImage per fare lo stesso. – user1198289

Problemi correlati