Hatena::Grouprubyist

yuisekiのいまさらruby厨日記

 | 

2010-07-18

sinatra+ziprubyでzipをオンメモリで動的に生成してレスポンスする

17:00 | はてなブックマーク - sinatra+ziprubyでzipをオンメモリで動的に生成してレスポンスする - yuisekiのいまさらruby厨日記

ユーザーごとに中身が別々のzipをダウンロードさせたいんだけど、いちいちzipファイルをディスクに保存したくないような時。


以下の例ではziprubyのZip::Archive.open_bufferメソッドで特定のディレクトリ内のファイルをまとめて圧縮して送信している。

ファイル名とファイル本体のバッファを保持しているハッシュの中身をユーザーごとにカスタマイズすれば、

好きなようにzipの中身をきめて、生成してダウンロードさせることができる。


Zip::Archive.open_bufferはメモリ上のバッファに書き出しが終わるまでレスポンスが送信されないのがちょっと難点で、

巨大すぎるファイルの圧縮だと時間が掛かり過ぎてタイムアウトになってしまうことがあるかもしれない。

メモリではなくTCPsocketにできたところから直接書き出しできれば多少はマシになると思われるので、

超巨大ファイルを圧縮転送したいひとはチャレンジしてやりかた教えてください。


参考までに、総容量100MB~200MB程度だと、ダウンロードして保存するダイアログの表示がちょっともたつく程度でタイムアウトまではしませんでした。


require 'rubygems'
require 'sinatra'
require 'zipruby'

get '/download.zip' do

  dir = '/home/sinatra/myapp/public/zip'
  files = []
  Dir::foreach(dir) {|f|
    next if f == "." or f == ".." or f == ".gitignore"
    files.push dirpath + "/" + f
  }

  file_buffers = Hash.new
  files.each do |path|
    # fileをbufferにためる
    filename = File::basename(path)
    file = open(path, "rb")
    file_buffers.store filename, file.read
    file.close
    # ファイルを閉じる
  end

  # オンメモリでzipファイルを生成
  zip_buffer = ''
  Zip::Archive.open_buffer(zip_buffer, Zip::CREATE, Zip::NO_COMPRESSION) do |zipb|
    # fileのbufferをzipのbufferにつっこんでいく
    file_buffers.each_pair do |filename, buf|
      zipb.add_buffer(filename, buf)
    end
  end

  # メモリ上のデータを送信
  content_type 'application/zip'
  attachment 'download.zip'
  zip_buffer

end


SayakaSayaka 2012/05/23 21:59 That's going to make tighns a lot easier from here on out.

zyatvyymzyatvyym 2012/05/24 11:54 2gr3aL <a href="http://njjtmbpctedu.com/">njjtmbpctedu</a>

saoojuyleosaoojuyleo 2012/05/25 15:34 kxC7n4 , [url=http://hvxfkwdogcpy.com/]hvxfkwdogcpy[/url], [link=http://galvvbjeavyt.com/]galvvbjeavyt[/link], http://emoyqlqfkqcp.com/

nlwrezvvnlwrezvv 2012/05/25 17:39 WYTuIr , [url=http://kbfvoraqnupu.com/]kbfvoraqnupu[/url], [link=http://dtlesdcbvtqv.com/]dtlesdcbvtqv[/link], http://hukmbaihsbpz.com/

tyaspupkmtyaspupkm 2012/05/26 16:13 m6FuPY <a href="http://vjmxozhghztm.com/">vjmxozhghztm</a>

iqswgjxkiqswgjxk 2012/05/26 20:49 rgzOZS , [url=http://lfrknwgtegbn.com/]lfrknwgtegbn[/url], [link=http://vuuqvbqwgmgv.com/]vuuqvbqwgmgv[/link], http://eakzqnhiravy.com/

ゲスト



トラックバック - http://rubyist.g.hatena.ne.jp/yuiseki/20100718
 |