2013-08-23 54 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

相关问题