====== Compressing a byte array in the ZIP format ======
**バイトarray**を圧縮したり、zipファイルを出力したりするのは、java.util.zipのAPIを用いれば簡単に出来る。\\
では、バイトarrayを圧縮してzipファイルで出力するのも可能なのか?結論から言えば可能だ。\\
しかし、あえてファイルではなくバイトアレイを圧縮する必要があるのか。もしファイルを作れない環境であれば((たとえば、サーバのファイルシステムが分からない場合や権限の為、ファイルの作成ができない場合だ。))十分考えられる状況である。\\
{{keywords>ByteArray create zip ZipEntry }}
===== Transfer bytes from a byte array to the ZIP file =====
private static final int COMPRESS_LEVEL = 9;
public long writeZipStream(byte[] input, OutputStream out, String entryName) throws IOException, ZipException{
// Create a buffer for reading a byte stream
byte[] buf = new byte[1024];
//Create the ZIP file
ZipOutputStream output = new ZipOutputStream(out);
//Create a zip entry
ZipEntry entry = new ZipEntry(entryName);
entry.setCompressedSize(getCompressedSize(input, entryName));
entry.setCrc(getCRCValue(input));
entry.setMethod(ZipEntry.DEFLATED);
//Add ZIP entry to output stream.
output.putNextEntry(entry);
//Transfer bytes from the file to the ZIP file
int len=0;
InputStream in = new ByteArrayInputStream(input);
while ((len = in.read(buf)) > 0) {
output.write(buf, 0, len);
}
// Complete the entry
output.closeEntry();
in.close();
//Complete the ZIP file
output.close();
return entry.getCompressedSize();
}//writeZipStream
private long getCompressedSize(byte[] input, String entryName) throws IOException {
ZipEntry entry = new ZipEntry(entryName);
entry.setMethod(ZipEntry.DEFLATED);
ZipOutputStream out = new ZipOutputStream(new IdleOutputStream());
out.setLevel(COMPRESS_LEVEL);
out.putNextEntry(entry);
BufferedInputStream in =
new BufferedInputStream(new ByteArrayInputStream(input));
int b=0;
while ((b = in.read()) != -1) {
out.write(b);
}
in.close();
out.closeEntry();
out.close();
return entry.getCompressedSize();
}
private long getCRCValue(byte[] input){
// Compute CRC-32 checksum
Checksum checksumEngine = new CRC32();
checksumEngine.update(input, 0, input.length);
long checksum = checksumEngine.getValue();
// The checksum engine can be reused again for a different byte array by calling reset()
checksumEngine.reset();
return checksum;
}
===== Example of compressing a byte array =====
ここで、肝心なのは圧縮の対象となるファイルのentry名を指定するところだ。\\
不思議にファイルを何も作っていないのに、まるで作られているように引数で渡している。\\
実際、"aaa.txt"というentry名が**%%ZipEntry%%**のconstructorに引数として渡されている。\\
なぜかというと、拡張子を含めてentry名を渡さなければ、圧縮対象ファイルの種類が分からない為だ。
byte[] buffer = ((ByteArrayOutputStream)out).toByteArray();
response.setContentType("Content-type: application/zip;");
response.addHeader("Content-Disposition", "attachment; filename=xxx.zip");
long contentLength = compressor.writeZipStream(buffer, out, "aaa.txt");
res.setHeader("Cache-Control","must-revalidate");
res.setHeader("Content-Length", String.valueOf(contentLength));
//
===== reference =====
- [[http://www.exampledepot.com/egs/java.util.zip/CompArray.html|Compressing a Byte Array]]