2013-08-23 57 views
6

我已經在內存中生成了許多BufferedImages,我想在將它們作爲電子郵件附件發送之前將它們壓縮到一個zip文件中。如何在不從磁盤讀取文件的情況下將文件保存爲zip文件。如何在不保存到Java磁盤的情況下生成zip文件?

有什麼辦法可以壓縮這些文件而不創建臨時文件?

由於創建了數千個文件,寫入磁盤非常耗時。

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

看看java.utli.zip。 –

+1

爲了我的好奇心,爲什麼要避免創建臨時文件? – 2013-08-23 15:09:39

+0

這似乎相關http://stackoverflow.com/questions/7108035/how-to-flush-the-zipoutputstream-periodically-in-java – Ted

回答

9

我不知道您在這裏,如果你有成千上萬的內存中的文件,你可能會相當快耗盡內存的使用情況。

但是,zip文件通常是使用流生成的,因此不需要將它們臨時存儲在文件中 - 也可以存儲在內存中或直接傳輸到遠程接收方(僅使用小內存緩衝區以避免大內存佔用)。

我發現了一個多年前寫的舊的zip實用程序,並稍微修改了它的用例。它從文件列表中創建一個存儲在字節數組中的zip文件,這些文件也存儲在字節數組中。既然你有很多文件在內存中表示,我添加了一個小幫助類MemoryFile只有文件名和一個包含內容的字節數組。哦,並且我公開了這些字段以避免樣板吸氣器/固定器的東西 - 當然這只是爲了節省一些空間。

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

我更新了我的原始帖子。我很困惑如何使用BufferImage來做同樣的事情。 – user1198289

+0

您不僅「更新」了原始帖子,而且完全改變了它。我不太喜歡那個;即在我花時間回答之後問題完全改變了。你應該知道,在內存中有成千上萬的PDF和成千上萬的BufferedImages是兩回事。對於每個圖像,都需要獲取格式爲(gif,png,jpg等)的輸出流,並且要保存/傳輸它們。還要注意,壓縮圖像對壓縮的影響很小,因爲他們通常已經被壓縮了。 – 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(); 

根據您所提供的信息,我想出了上面的代碼。希望這可以幫助。

+0

我更新了我原來的帖子。我很困惑如何使用BufferImage來做同樣的事情。 – user1198289

相關問題