Writing /volume1/Web/Public/dokuwiki/data/log/deprecated/2024-11-13.log failed
目次
Compressing a byte array in the ZIP format
バイトarrayを圧縮したり、zipファイルを出力したりするのは、java.util.zipのAPIを用いれば簡単に出来る。
では、バイトarrayを圧縮してzipファイルで出力するのも可能なのか?結論から言えば可能だ。
しかし、あえてファイルではなくバイトアレイを圧縮する必要があるのか。もしファイルを作れない環境であれば1)十分考えられる状況である。
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
1)
たとえば、サーバのファイルシステムが分からない場合や権限の為、ファイルの作成ができない場合だ。