本文介绍了Rails:zip 格式的即时输出流?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在一个 zip 文件中提供我的数据库中的一些数据,并即时流式传输它,以便:

I need to serve some data from my database in a zip file, streaming it on the fly such that:

  • 我不会将临时文件写入磁盘
  • 我不会在 RAM 中编写整个文件

我知道我可以使用 ZipOutputStream 作为 此处.我也知道我可以通过将 response_body 设置为 Proc 作为 此处.我需要(我认为)是一种将这两件事结合在一起的方法.我可以让 rails 提供来自 ZipOutputStream 的响应吗?我可以获得 ZipOutputStream 给我的增量数据块,我可以将其输入到我的 response_body Proc 中吗?或者有其他方法吗?

I know that I can do streaming generation of zip files to the filesystemk using ZipOutputStream as here. I also know that I can do streaming output from a rails controller by setting response_body to a Proc as here. What I need (I think) is a way of plugging those two things together. Can I make rails serve a response from a ZipOutputStream? Can I get ZipOutputStream give me incremental chunks of data that I can feed into my response_body Proc? Or is there another way?

推荐答案

我遇到了类似的问题.我不需要直接流式传输,但只有第一种不想写临时文件的情况.您可以轻松修改 ZipOutputStream 以接受 IO 对象,而不仅仅是文件名.

I had a similar issue. I didn't need to stream directly, but only had your first case of not wanting to write a temp file. You can easily modify ZipOutputStream to accept an IO object instead of just a filename.

module Zip
  class IOOutputStream < ZipOutputStream
    def initialize io
      super '-'
      @outputStream = io
    end

    def stream
      @outputStream
    end
  end
end

从那里开始,它应该只是在您的 Proc 中使用新的 Zip::IOOutputStream 的问题.在您的控制器中,您可能会执行以下操作:

From there, it should just be a matter of using the new Zip::IOOutputStream in your Proc. In your controller, you'd probably do something like:

self.response_body =  proc do |response, output|
  Zip::IOOutputStream.open(output) do |zip|
    my_files.each do |file|
      zip.put_next_entry file
      zip << IO.read file
    end
  end
end

这篇关于Rails:zip 格式的即时输出流?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-12 16:36