null byteエラーが発生したときの対処
やりたいこと
①S3から複数のZipファイルを取得
②複数のzipファイルを解凍しディレクトリ形式にする
③最終的に1つのzipファイルにしたい。
起きた問題
①でget_objectしたところ、以下のようになってしまい、②で必要なファイルパスが取得できない状況。
PK\u0003\u0004\u0014\u0000\u0000\u0000\u0000\u0000\xA1\x9AYQ\u0000\u0000\u0000
client = Aws::S3::Client.new( :region => 'ap-northeast-1', :access_key_id => '***', :secret_access_key => '***', ) @orders.each do |order| obj = client.get_object( bucket: "*", key: order.zip_file_name ).body.read Rails.logger.debug obj.inspect #=> PK\u0003\u0004\u0014\u0000\u00.... end
原因
zipファイルの中身はバイナリデータ。
ダウンロードしてきたファイルの中身をobjに参照させている。.body.read
という関数は、zipファイルの中身を参照する関数。なので、当然バイナリがログで出てくる。
解決策
readせずに、rubyzipのopen_buffer
メソッドを使って、zipファイルを開く。
ただ、open_bufferメソッドはrubyzipの公式ドキュメントには載っていない。。。
もっと良いやり方見つけたい。
client = Aws::S3::Client.new( :region => 'ap-northeast-1', :access_key_id => '***', :secret_access_key => '***', ) @orders.each do |order| obj = client.get_object( bucket: "*", key: order.zip_file_name ).body >> readしない! end ## get_objectでopenする Zip::File.open_buffer(obj) do |zip| ~~ end