読者です 読者をやめる 読者になる 読者になる

プログラムdeタマゴ

nodamushiの著作物は、文章、画像、プログラムにかかわらず全てUnlicenseです

JAVAでZIP

JAVAでzip圧縮するにはDeflaterクラスを、解凍するにはInflaterクラスを利用できます。
ファイルに出力するならZipOutputStreamを使う。そっちの解説はネット上にごろごろ転がってるけど、DeflaterやInflaterに関しては情報少ないのでここでメモ。
 
DeflaterではByte単位で圧縮していく。
そのため、データもByte単位で数値化するのが言い。一つのデータがnbitに収まるからといって、nbit単位で書き込んでいったりはしない方が良い。
特に、データの数列に偏りを持たせたときに、その偏りが壊れてしまうという事態になるので、バイト単位で書き込んでいくこと。
 
書き込むにはsetImput関数を使う。
setInput( byte b)という関数があるが、なぜかこっちは例外投げるので面倒だから使わない。
基本的にはsetInput( byte
b, int offset, int len)を使う。offsetは配列bの開始位置。
 
書き込みが終わったら一応finishを呼び出しておく。間違ってもendを呼んではいけない。
 
さて、次に圧縮データを取り出す作業に入る。
圧縮した後のデータサイズを直接得る方法はない。これ取得できるようになぜしなかったのだろうか?
 
ByteArrayOutputSteamなりを用意しておいて、こんな感じにするしかないと思われる。

ByteArrayOutputStream o = new ByteArrayOutputStream();
byte buffer = new byte[1000];
int write = deflater.deflate(buffer,0,1000);
while(write!=0){
    o.write(buffer,0,write);
    write = delater.deflate(buffer,0,1000);
}
byte
data = o.toByteArray();
 
//読み出した長さを取得する場合は下の方法も使える
int length = deflater.getTotalOut() ;//int型最大値を超える場合はおかしくなる
long length=deflater.getBytesWritten();//こちらの方が値は正確


 
使い終わったら一応end()を呼び出してメモリを解放しておこう。
 
 
Inflaterに関してもほぼ同様。