有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

如何生成zip文件而不使用Java保存到磁盘?

我在内存中生成了许多BuffereImage,我想在将其作为电子邮件附件发送之前将其压缩到一个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));
    }
}

共 (2) 个答案

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

    根据你提供的信息,我想出了上面的代码。希望这有帮助

  2. # 2 楼答案

    我不确定你现在使用的用例,如果你有数千个文件在内存中,你可能会很快耗尽内存

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