rubyのZlibで2G以上の容量の大きなファイルを扱う場合

parser = XML::SaxParser.io Zlib::GzipReader.open(output_file_name)
parser.callbacks = HogeListener.new
parser.parse

〜.gzなどのoutput_file_nameが2Gが以下なら上記で問題なし。ただし、2Gを超えると、GzipReader::LengthErrorが発生します。これによりファイルの最後の方の読み込みが失敗してしまいます。
Ruby/zlib version 0.3.0
理由は、gzipは2G以上の大容量のファイルをサポートしていなからで、2Gを超えた場合、フッターなどのファイル情報が正しくないためです。

そこで、http://europe.ciao.jp/solaris/gzip/index.htmlを参考に、下記のようにしてやれば解決しました。

parser = XML::SaxParser.io IO.popen("cat #{output_file_name} | gzip -d")
parser.callbacks = HogeListener.new
parser.parse

ちなみにpopenの引数には、コマンドラインで実行できるコマンドを書くことが出来ます。
IO.popen(cmd_string, "r+") { |io| block } 便利だな - uzullaの日記 - 1981s


なお、バッククォートメソッドの戻り値は標準出力となます。

test = `cat #{output_file_name} | gzip -d`
puts test.class

で「string」と出力されます。

始め、popenの引数には、文字列を入れるものだと思い、下記のようにやって「hoge_batch.rb:75:in `popen': failed to allocate memory (NoMemoryError)」というエラーが出ていました。。

parser = XML::SaxParser.io IO.popen(`cat #{output_file_name} | gzip -d`)
・
・

にほんブログ村 IT技術ブログへ
1票ポチッと押して下さい♪このブログのランキングが少し上がります。