【问题标题】:Why is AWS uploading literal file paths, instead of uploading images?为什么 AWS 上传文字文件路径,而不是上传图片?
【发布时间】:2021-11-09 18:26:43
【问题描述】:

TL;DR

如何将文件路径输入 AWS S3 API Ruby 客户端,并将它们解释为图像,而不是字符串文字文件路径?

更多详情

我正在使用 Ruby AWS S3 客户端以编程方式上传图像。我从他们的示例启动代码中获取了这段代码,我自己几乎没有修改过。见https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/s3-example-upload-bucket-item.html

def object_uploaded?(s3_client, bucket_name, object_key)
    response = s3_client.put_object(
      body:   "tmp/cosn_img.jpeg", # is always interpreted literally
      acl:    "public-read",
      bucket: bucket_name,
      key:    object_key
    )
    if response.etag
      return true
    else
      return false
    end
  rescue StandardError => e
    puts "Error uploading object: #{e.message}"
    return false
  end

  # Full example call:
  def run_me
    bucket_name = 'cosn-images'
    object_key =  "#{order_number}-trello-pic_#{list_config[:ac_campaign_id]}.jpeg"
    region = 'us-west-2'
    s3_client = Aws::S3::Client.new(region: region)

    if object_uploaded?(s3_client, bucket_name, object_key)
      puts "Object '#{object_key}' uploaded to bucket '#{bucket_name}'."
    else
      puts "Object '#{object_key}' not uploaded to bucket '#{bucket_name}'."
    end
  end

这可行并且能够上传到 AWS,但它只是从正文上传文件 path,而不是实际文件本身。

点击附件链接时显示的文件路径

据我从客户端文档中看到的,这应该有效。 https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#put_object-instance_method

客户文档

另外,通过前端手动上传这个文件确实可以正常工作,所以它必须是我的代码中的一个问题。

您应该如何让 AWS 知道它应该将该文件路径解释为文件路径,而不仅仅是字符串文字?

【问题讨论】:

  • 使用upload_file 代替put_object。否则你可以做body: open("tmp/cosn_img.jpeg", 'r').read()
  • @jordanm 你能扩展你的答案吗?我尝试使用body: open("tmp/cosn_img.jpeg", 'r').read(),但这似乎不起作用。它只是返回一个空字符串。而且我不确定如何将upload_file 与其余的流程和身份验证结合起来。
  • 您必须以'rb' 模式而不是'r' 模式读取文件才能正确读取图像文件

标签: ruby-on-rails ruby amazon-web-services amazon-s3 filepath


【解决方案1】:

他们的文档看起来有点怪异且不直截了当,但似乎您可能需要传入文件/io 对象,而不是路径。

ruby docs here 有一个这样的例子:

s3_client.put_object(
  :bucket_name => 'mybucket',
  :key => 'some/key'
  :content_length => File.size('myfile.txt')
) do |buffer|
  File.open('myfile.txt') do |io|
    buffer.write(io.read(length)) until io.eof?
  end
end

aws ruby sdk docs 中的另一个选项,在“从磁盘流式传输文件”下:

File.open('/source/file/path', 'rb') do |file|
  s3.put_object(bucket: 'bucket-name', key: 'object-key', body: file)
end

【讨论】:

    【解决方案2】:

    你有两个问题:

    1. object_uploaded? 中变量赋值的末尾有逗号,这会影响变量的存储方式。删除这些。
    2. 您需要将文件引用为文件对象类型,而不是文件路径。像这样:
    image = File.open("#{Rails.root}/tmp/cosn_img.jpeg")
    

    查看下面的完整代码:

    def object_uploaded?(image, s3_client, bucket_name, object_key)
      response = s3_client.put_object(
        body:   image,
        acl:    "public-read",
        bucket: bucket_name,
        key:    object_key
      )
      puts response
      if response.etag
        return true
      else
        return false
      end
    rescue StandardError => e
      puts "Error uploading object: #{e.message}"
      return false
    end
    
    def run_me
      image = File.open("#{Rails.root}/tmp/cosn_img.jpeg")
      bucket_name = 'cosn-images'
      object_key =  "#{order_number}-trello-pic_#{list_config[:ac_campaign_id]}.jpeg"
      region = 'us-west-2'
      s3_client = Aws::S3::Client.new(region: region)
    
      if object_uploaded?(image, s3_client, bucket_name, object_key)
        puts "Object '#{object_key}' uploaded to bucket '#{bucket_name}'."
      else
        puts "Object '#{object_key}' not uploaded to bucket '#{bucket_name}'."
      end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-21
      • 1970-01-01
      • 2016-07-11
      • 1970-01-01
      • 1970-01-01
      • 2014-05-16
      • 1970-01-01
      相关资源
      最近更新 更多