使用aws-sdk在rails中为ruby下载S3文件(对象)

ora*_*e88 5 ruby forms ruby-on-rails amazon-s3 amazon-web-services

我没有使用paperclip或carrierwave或任何其他宝石与亚马逊网络服务s3进行交互.事实上,我没有使用任何模型,只是直接与S3对象进行交互.

有人可以提供一些代码来说明如何从AWS S3直接下载对象(文件)

到目前为止这是我的代码:

视图:

<h2>Download Files</h2>
<%@root_files.each do |file| %>
<% next if @obj %>        
<td>Filename:  <b><%= file %></b></td>
<td><%= link_to "Download", download_url_for(file) %></td>
<% end %>
Run Code Online (Sandbox Code Playgroud)

对应控制器:

def xxx
bucket = AWS::S3.new.buckets[ ENV["BUCKET"]]
@root_files = bucket.as_tree.children.select(&:leaf?).collect(&:key) 
end
Run Code Online (Sandbox Code Playgroud)

download_url_for方法:

def download_url_for(file_key)
  s3 = AWS::S3.new
  bucket = s3.buckets[ ENV["BUCKET"]]
  object = bucket.objects[file_key]
  File.open('xxxxx', 'wb') do |file|
    object.read do |chunk|
      file.write(chunk)
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

我需要能够将下载的文件保存在桌面上任何可浏览的非预定位置.我真的很感激如何修改download_url_for方法以实现此目的.

=====================================我刚试过用

<td><%= link_to "Download",object.value.url_for(:read).to_s %></td>
Run Code Online (Sandbox Code Playgroud)

但是在下载时我只得到一个带有xml内容的zip文件,而不是原始文件(在我的情况下是word文档)---有关如何修改它以获取实际文件类型和内容的任何想法?谢谢

=======================继承我上传文件的代码

查看代码:

<%= form_tag({:action => 'create_file'}, multipart: true) do %>
<%= file_field_tag 'uploaded_file' %><br />
<%= submit_tag 'Upload' %> <br />
<% end %>
Run Code Online (Sandbox Code Playgroud)

控制器操作 - create_file操作

def create_file 
s3 = AWS::S3.new
bucket = s3.buckets[ENV["BUCKET"]]
key = params[:uploaded_file].original_filename
object = bucket.objects[key] 
object.write(params[:uploaded_file].read)
end
Run Code Online (Sandbox Code Playgroud)

有人建议如何在上传时检查MIME类型或保留文件名,如果这是@Frederick Cheung提到的问题吗?谢谢

ros*_*sta 2

您最好为用户提供直接从 S3 下载的 URL,而不是尝试通过 Rails 应用程序流式传输文件。

aws-sdk 提供了url_for完成此操作的方法:http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/S3/S3Object.html#url_for-instance_method。它需要一堆关于过期、安全、缓存等的选项。一个基本的例子:

<td><%= link_to "Download", file.url_for(:read) %></td>
Run Code Online (Sandbox Code Playgroud)

- 编辑 -

要访问url_for视图中的方法,您需要引用 s3 对象。因此,在控制器中,您希望从叶节点收集对象,而不是键:

@root_files = bucket.as_tree.children.select(&:leaf?).collect(&:object)
Run Code Online (Sandbox Code Playgroud)