2013-08-23 8 views
6

Ich habe viele BufferedImages im Speicher generiert und möchte sie in eine Zip-Datei komprimieren, bevor ich sie als E-Mail-Anhang sende. Wie speichere ich die Dateien in eine Zip ohne Dateien von der Festplatte zu lesen.Wie kann ich eine Zip-Datei ohne Speichern auf der Festplatte mit Java generieren?

Gibt es eine Möglichkeit, diese Dateien zu komprimieren, ohne eine temporäre Datei zu erstellen?

Das Schreiben auf die Festplatte ist zeitaufwendig, da Tausende von Dateien erstellt werden.

/* 
* 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

Schauen Sie sich java.utli.zip an. –

+1

Nur für meine Neugier, warum möchten Sie vermeiden, eine temporäre Datei zu erstellen? –

+0

Dies scheint verwandt http://stackoverflow.com/questions/7108035/how-to-flush-the-zipoutputstream-periodically-in-java – Ted

Antwort

9

Ich bin mir nicht sicher über die Use-Case Sie hier mit sind, wenn Sie Tausende von Dateien im Speicher haben Sie könnten ziemlich schnell aus dem Speicher ausgeführt werden.

Zip-Dateien werden jedoch normalerweise mit Streams generiert, so dass sie nicht vorübergehend in einer Datei gespeichert werden müssen - möglicherweise auch im Arbeitsspeicher oder direkt an einen Remoteempfänger gestreamt werden (mit nur einem kleinen Speicherpuffer) großer Speicherbedarf).

Ich habe vor Jahren ein altes Zip-Dienstprogramm gefunden und es leicht für Ihren Anwendungsfall modifiziert. Es erstellt eine Zip-Datei, die in einem Byte-Array gespeichert ist, aus einer Liste von Dateien, die ebenfalls in Byte-Arrays gespeichert sind. Da Sie viele Dateien im Speicher haben, habe ich eine kleine Hilfsklasse MemoryFile mit nur dem Dateinamen und einem Byte-Array mit dem Inhalt hinzugefügt. Ach ja, und ich habe die Felder öffentlich gemacht, um das Getter/Setter-Zeug zu vermeiden - nur um hier natürlich Platz zu sparen.

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

Ich habe meinen ursprünglichen Post aktualisiert. Ich war verwirrt, wie ein BufferImage verwendet werden könnte, um das Gleiche zu tun. – user1198289

+0

Sie haben Ihren ursprünglichen Beitrag nicht nur "aktualisiert", Sie haben ihn komplett geändert. Ich mag das nicht besonders; Das heißt, dass die Frage völlig geändert wird, nachdem ich Zeit damit verbracht habe, sie zu beantworten. Sie sollten wissen, dass "Tausende" von PDFs im Speicher und Tausende von BufferedImages zwei verschiedene Dinge sind. Für jedes Bild müssen Sie einen Ausgabestrom im Format (gif, png, jpg usw.) erhalten, in dem Sie sie speichern/übertragen möchten. Beachten Sie auch, dass das Komprimieren von Bildern nur geringe Auswirkungen hat, da Sie sind normalerweise bereits komprimiert. – 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(); 

Basierend auf den Informationen, die Sie zur Verfügung gestellt haben, komme ich oben mit dem Code auf. Hoffe das hilft.

+0

Ich habe meinen ursprünglichen Post aktualisiert. Ich war verwirrt, wie ein BufferImage verwendet werden könnte, um das Gleiche zu tun. – user1198289

Verwandte Themen