LoginSignup
0
0

More than 1 year has passed since last update.

Gzip圧縮したデータを連結したデータはRubyのZlib::GzipReaderでは読めない

Posted at

複数のGzipデータを連結した1つのデータ

gzipコマンドは複数のgzip圧縮されたファイルをcatで結合したものでも展開することができます。簡単な例をbashで見てみましょう

date --iso-8601=ns | gzip > a.gz
date --iso-8601=ns | gzip > b.gz
cat a.gz b.gz > all.gz
gzip -dc all.gz # 2行出てくる

RFC1952でファイルフォーマットについて説明があります。

Gzipファイルフォーマットは先頭10byteは必ずメンバ情報になっており、あとはメンバ情報のFLGによって可変長データが続くような形になっています。

この繰り返しなので、複数の圧縮されたデータがあっても、ひたすら展開して連結することで1つのデータが得られる仕組みになっているようです。上記の通り、gzipコマンドやzcatコマンドや著名なアーカイバ(7-zipとか)はサポートしています。

RubyのZlib::GzipReaderはサポートしているか?

2021/10/05時点の実装ではZlib::GzipReader.zcatでサポートしているようですが、RubyGemsで公開されているバージョン(1.1.0)ではまだ入っていないようで、まだサポートされていない、といえる状態です。

なので、適当に処理するしかないので、こんな感じにします。Rubyは全く書かないので、この実装で良いかは怪しいです。

def uncompress(gzip_data)
      decoded_data = ""
      while gzip_data do
        Zlib::GzipReader.wrap(StringIO.new(gzip_data.b)) do |gz|
          decoded_data << gz.read
          gzip_data = gz.unused
        end
      end
      decoded_data
end

readで1つ分は読めて、unusedに余ったデータが残るので、残ったデータに対してまたreadを繰り返して連結していきます。
雑過ぎますが、テストコードで必要になった実装なので雑でいいんです(いいのか?)

zcatが待ち遠しいですね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0