我的环境:
当文件大小低于2G时,一切顺利。
class ItemListsController < ApplicationController
...
send_data IO.read(zip_path), :type => 'application/zip',
:disposition => 'attachment',
:filename => file_name
但是,当文件大小大于2G时,会引发异常:
Errno::EINVAL: Invalid argument @ io_fread
我尝试使用rubyzip来输出流:
compressed_filestream = Zip::OutputStream.write_buffer do |zos|
files.each do |file|
zos.put_next_entry file[1]
zos.write File.open(file[0], 'r').read
end
end
compressed_filestream.rewind
send_data compressed_filestream.read, :type => 'application/zip',
:disposition => 'attachment',
:filename => file_name
进一步详细说明的例外情况:
Unexpected error while processing request: integer 2206004964 too big to convert to `int'
/Users/karl/.rvm/gems/ruby-2.1.4@hcsvlab/gems/eventmachine-1.0.3/lib/em/connection.rb:328:in `send_data'
似乎send_data会将整个文件读入内存然后再发回数据。
我原来的计划是找到一些提供“缓冲区”的方法,这样send_data会从缓冲区中读取而不是读取整个文件,但是在API中找不到这样的选项
https://apidock.com/rails/ActionController/DataStreaming/send_data
任何想法都将不胜感激。
感谢。
答案 0 :(得分:0)
您可能希望改用send_file
。根据{{3}}:
发送文件,默认情况下一次流式传输4096个字节。这条路 整个文件不需要立即读入内存。这使得 发送大型文件是可行的。您可以选择关闭 流式传输并立即发送整个文件。