send_file 用于 Sinatra 中的临时文件

Posted

技术标签:

【中文标题】send_file 用于 Sinatra 中的临时文件【英文标题】:send_file for a tempfile in Sinatra 【发布时间】:2013-03-03 07:51:40 【问题描述】:

我正在尝试使用 Sinatra 的内置 send_file 命令,但它似乎不适用于临时文件。

我基本上会执行以下操作来压缩 mp3 专辑:

get '/example' do
  songs = ...
  file_name = "zip_test.zip"
  t = Tempfile.new(['temp_zip', '.zip'])
  # t = File.new("testfile.zip", "w")
  Zip::ZipOutputStream.open(t.path) do |z|
    songs.each do |song|
      name = song.name
      name += ".mp3" unless name.end_with?(".mp3")
      z.put_next_entry(name)
      z.print(open(song.url) |f| f.read )
      p song.name + ' added to file'
    end
  end
  p t.path
  p t.size

  send_file t.path, :type => 'application/zip',
                         :disposition => 'attachment',
                         :filename => file_name,
                          :stream => false
  t.close
  t.unlink
end

当我使用t = File.new(...) 时,一切正常,但我不想使用File,因为它会出现并发问题。

当我使用t = Tempfile.new(...) 时,我得到:

!! Unexpected error while processing request: The file identified by body.to_path does not exist`

编辑:看起来问题的一部分是我正在发送多个文件。如果我只发送一首歌曲,Tempfile 系统也能正常工作。

【问题讨论】:

如果您使用包含多个文件的预构建 zip 文件而不是使用 Zip::ZipOutputStream.open... 会发生什么?另外,send_file sends a halt 所以不需要t.closet.unlink(无论如何文件系统都应该为你处理这个问题)。 【参考方案1】:

我的猜测是您的歌曲名称中有一个拼写错误,或者可能是 song.url 的最后一部分中的一个斜线?我adopted your code 如果所有歌曲都存在,那么将 zip 作为临时文件发送就可以了。

【讨论】:

以上是关于send_file 用于 Sinatra 中的临时文件的主要内容,如果未能解决你的问题,请参考以下文章

NamedTemporaryFile() 用于在烧瓶 send_file 之后清除文件

烧瓶 send_file 不适用于 tar.gz 文件

Python Flask send_file StringIO 空白文件

在 MacRuby 应用程序中运行 Sinatra

使用烧瓶中的 send_file() 时文件损坏,pymongo gridfs 中的数据

使用Python Flask中的send_file发送视频时移动设备发生错误http://mattspitz.me/2013/11/20/serving-authenticated-media-wit