Hatena::ブログ(Diary)

三十路エンジニアの備忘録+α

2009-09-04

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

| 01:32 | 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を超えた場合、フッターなどのファイル情報が正しくないためです。

そこで、404 Error - Not Foundを参考に、下記のようにしてやれば解決しました。

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票ポチッと押して下さい♪このブログのランキングが少し上がります。

トラックバック - http://d.hatena.ne.jp/rockstar2007/20090904/1252081920