🎅

【Rails】null byteエラーが発生した時の対処

2020/12/25に公開

やりたいこと

①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

Discussion

ログインするとコメントできます