开发者

Ruby zip a stream

I am trying to write a ruby fcgi script w开发者_Go百科hich compresses files in a directory on the fly and sends the output blockwise as an http response. It is very important that this compression is done as a stream operation, otherwise the client will get a timeout for huge directories.

I have the following code:

d="/tmp/delivery/"

# send zip header
header(MimeTypes::ZIP)

# pseudocode from here on
IO.open(d) { |fh|
    block=fh.readblock(1024)
    #send zipped block as http response
    print zip_it(block)
}

How do I achieve what I've written as pseudo-ruby in the above listing?


Tokland's idea of using the external zip command works pretty well. Here's a quick snippet that should work with Ruby 1.9 on Linux or similar environments. It uses an array parameter to popen() to avoid any shell quoting issues and sysread/syswrite to avoid buffering. You could display a status message in the empty rescue block if you like -- or you could use read and write, though I haven't tested those.

#! usr/bin/env ruby
d = '/tmp/delivery'
output = $stdout
IO.popen(['/usr/bin/zip', '-', d]) do |zip_output|
  begin
    while buf = zip_output.sysread(1024)
      output.syswrite(buf)
    end
    rescue EOFError
  end
end


AFAYK Zip format is not streamable, at end of compression it writes something in the file header.

gz or tar.gz is better option.


solved:

https://github.com/fringd/zipline.git

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜