差分
このページの2つのバージョン間の差分を表示します。
| 次のリビジョン | 前のリビジョン | ||
| study:java:compress [2008/04/30 05:43] – created banana | study:java:compress [2010/04/05 14:44] (現在) – banana | ||
|---|---|---|---|
| 行 1: | 行 1: | ||
| - | ====== Compressing a byte array to a zip file ====== | + | ====== Compressing a byte array in the ZIP format |
| - | **バイトarray**を圧縮したり、zipファイルを圧縮したりするのは、java.util.zipのAPIを用いれば簡単に出来る。\\ | + | **バイトarray**を圧縮したり、zipファイルを出力したりするのは、java.util.zipのAPIを用いれば簡単に出来る。\\ |
| では、バイトarrayを圧縮してzipファイルで出力するのも可能なのか?結論から言えば可能だ。\\ | では、バイトarrayを圧縮してzipファイルで出力するのも可能なのか?結論から言えば可能だ。\\ | ||
| - | しかし、あえてファイルではなくバイトアレイを圧縮する必要があるのか。もしファイルを作れない環境であれば((たとえば、サーバのファイルシステムが分からない場合や権限の為、ファイルの作成ができない場合だ。))十分考えられる状況だ。\\ | + | しかし、あえてファイルではなくバイトアレイを圧縮する必要があるのか。もしファイルを作れない環境であれば((たとえば、サーバのファイルシステムが分からない場合や権限の為、ファイルの作成ができない場合だ。))十分考えられる状況である。\\ |
| + | |||
| + | {{keywords> | ||
| + | |||
| + | ===== Transfer bytes from a byte array to the ZIP file ===== | ||
| + | |||
| + | <code java> | ||
| + | private static final int COMPRESS_LEVEL = 9; | ||
| + | |||
| + | public long writeZipStream(byte[] input, OutputStream out, String entryName) throws IOException, | ||
| + | // 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, | ||
| + | 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, | ||
| + | } | ||
| + | |||
| + | // Complete the entry | ||
| + | output.closeEntry(); | ||
| + | in.close(); | ||
| + | |||
| + | //Complete the ZIP file | ||
| + | output.close(); | ||
| + | |||
| + | |||
| + | return entry.getCompressedSize(); | ||
| + | }// | ||
| + | |||
| + | 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, | ||
| + | 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名を指定するところだ。\\ | ||
| + | 不思議にファイルを何も作っていないのに、まるで作られているように引数で渡している。\\ | ||
| + | 実際、" | ||
| + | なぜかというと、拡張子を含めてentry名を渡さなければ、圧縮対象ファイルの種類が分からない為だ。 | ||
| + | |||
| + | <code java> | ||
| + | byte[] buffer = ((ByteArrayOutputStream)out).toByteArray(); | ||
| + | |||
| + | response.setContentType(" | ||
| + | response.addHeader(" | ||
| + | |||
| + | long contentLength = compressor.writeZipStream(buffer, | ||
| + | res.setHeader(" | ||
| + | res.setHeader(" | ||
| + | // | ||
| + | </ | ||
| + | |||
| + | ===== reference ===== | ||
| + | - [[http:// | ||