17

メモリ内に多数の BufferedImages を生成しました。それらを 1 つの 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));
    }
}
4

2 に答える 2

24

ここでのユースケースについてはわかりません。メモリに何千ものファイルがある場合、メモリがすぐに不足する可能性があります。

ただし、通常、zip ファイルはいずれにしてもストリームで生成されるため、それらを一時的にファイルに保存する必要はありません。メモリ内に置くか、リモートの受信者に直接ストリーミングすることもできます (大きなメモリ フットプリントを避けるために小さなメモリ バッファのみを使用)。 .

何年も前に書かれた古い zip ユーティリティを見つけて、ユースケースに合わせて少し変更しました。バイト配列に格納されたファイルのリストから、バイト配列に格納された zip ファイルを作成します。MemoryFileメモリ内に多数のファイルが表示されているため、ファイル名と内容を含むバイト配列だけを持つ小さなヘルパー クラスを追加しました。ああ、私はフィールドを public にして定型的な 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();
    }

}
于 2013-08-23T15:48:15.837 に答える