我在内存中生成了许多BufferedImages,我想将它们压缩成一个zip文件,然后再将其作为电子邮件附件发送。如何在不从磁盘读取文件的情况下将文件保存为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));
}
}
答案 0 :(得分:17)
我不确定你在这里使用的用例,如果内存中有数千个文件,你可能会很快耗尽内存。
但是,zip文件通常是使用流生成的,所以不需要将它们临时存储在文件中 - 也可以在内存中或直接流式传输到远程接收者(只需要很小的内存缓冲区以避免大记忆足迹)。
我在几年前发现了一个旧的zip实用程序,并根据您的用例略微修改了它。它创建一个zip文件,存储在一个文件列表的字节数组中,也存储在字节数组中。由于你在内存中有很多文件,我添加了一个小帮助器类MemoryFile
,只有文件名和包含内容的字节数组。哦,我把这些字段公之于众,以避免使用样板getter / setter的东西 - 只是为了节省一些空间。
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();
}
}
答案 1 :(得分: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();
根据您提供的信息,我想出了上面的代码。希望这会有所帮助。