うえの@ぶるーすかいです。

Ruby/zlib version 0.3.0 をリリースします。

  http://www.blue.sky.or.jp/atelier/ruby/ruby-zlib-0.3.0.tar.gz


From: Tanaka Akira <akr / m17n.org>
> が、([] + (1..1000)).join の場合にはうまくいきません。
>
> require 'zlib'
>
> data1 = ([] + (1..1000)).join
>
> deflate = Deflate.new
>
> compressed = deflate.deflate(data1)
> compressed += deflate.deflate("", Deflate::SYNC_FLUSH)
>
> inflate = Inflate.new
> data2 = inflate.inflate(compressed)
>
> print data1.length, "\n"
> print data2.length, "\n"
>
> とすると、
>
> 2893
> 1024
>
> となります。つまり、展開結果が 1024byte にしかなりません。

Deflate.new を使って圧縮する場合、finish メソッドで
圧縮ストリームを明示的に終了させる必要があります。

require 'zlib'

data1 = ([] + (1..1000)).join

deflate = Deflate.new

compressed = deflate.deflate(data1)
compressed += deflate.deflate("", Deflate::SYNC_FLUSH)  # 本質的には不要
compressed2 = deflate.finish
# compressed + compressed2 が有効な圧縮データとなる。
# 「finish が呼ばれて初めて全入力と全出力が対応します」ってヤツです。

inflate = Inflate.new
data2 = inflate.inflate(compressed)
data3 = inflate.inflate(compressed2)
data4 = inflate.finish     # 不要だがエラーチェックになる

print data1.length, "\n"   # => 2893
print data2.length, "\n"   # => 1024
print data3.length, "\n"   # => 1869
print data4.length, "\n"   # => 0


ちなみに、deflate/inflate メソッドの返り値を保存するのが煩わしいなら、
<< メソッドを使って ZStream の内部バッファに保存させ
後で finish や flush_out で一気に取り出す、といったこともできます。


# 個々のクラスやメソッドの解説だけして、実際どのように使うかを
# 解説していないのが Ruby/zlib のドキュメントの悪いところ
# なんですよねぇ…
# 分かってはいるんですが (^^;;


-=====--===-
   うえの かつひろ @ BLUE-SKYNET    <unnie / blue.sky.or.jp>  --=
---=----===-                    http://www.blue.sky.or.jp/  -==