tkm9

自分向け技術メモ(?)

rails で ファイルをディレクトリに入れたものをzip圧縮して返す

rails 4.2 / ruby 2.1.5

やりたいこと

zip ファイルを一時ファイルとして生成して、レスポンスで返したい。

返した zip を展開すると

└ test_dir
   ├── text.txt
   └── foo.png

こんなかんじに、test_dir の中にファイルが格納されてる状態になっててほしい。

コード

今回 rubyzip を使用しました。

require 'zip'
def zip_test
  filename  = 'test_zip.zip'
  dirname   = "test_dir"
  temp_file = Tempfile.new(filename)
  begin
    Zip::File.open(temp_file.path, Zip::File::CREATE) do |zip|
      # (1) ZIP内にディレクトリを作成
      zip.mkdir dirname

      # (2) 作ったディレクトリにファイルを書き込む1
      zip.get_output_stream( dirname + "/test.txt" ){ |s| s.print( "AAAAAAA" ) }

      # (3) 作ったディレクトリにファイルを書き込む2(既存ファイルから)
      open("/tmp/foo.png") do |f|
        zip.get_output_stream( dirname + "/" + File.basename(f.path)){|s| s.print( f.read ) }
      end

    end
    zip_data = File.read(temp_file.path)
    send_data(zip_data, :type => 'application/zip', :filename => filename)
  ensure
    temp_file.close
    temp_file.unlink
  end
end

こんな感じにしました。