上传 / post stringIO 作为文件

upload / post stringIO as file

我想将 stringIO 作为文件上传到服务器。 我没有使用 rails 来发出请求,只是 ruby 和一些 gem。 我创建了一个如下所示的 stringIO:

require 'rest-client'
require 'zip'

... some code
stream = Zip::OutputStream::write_buffer do |zip|
  ... code that download files and packs them
end

stream.rewind

RestClient.post('somepath', { file: stream.read }, headers)

RestClient 只是一些方便的 gem,它使发送 http 请求更容易一些。 所以我的问题是当我收到请求时在控制器的服务器端出现错误

ArgumentError - invalid byte sequence in UTF-8:
  activesupport (4.2.6) lib/active_support/core_ext/object/blank.rb:117:in `blank?'
  carrierwave (0.10.0) lib/carrierwave/sanitized_file.rb:127:in `is_path?'
  carrierwave (0.10.0) lib/carrierwave/sanitized_file.rb:93:in `size'
  carrierwave (0.10.0) lib/carrierwave/sanitized_file.rb:136:in `empty?'
  carrierwave (0.10.0) lib/carrierwave/uploader/cache.rb:119:in `cache!'
  carrierwave (0.10.0) lib/carrierwave/mount.rb:329:in `cache'
  carrierwave (0.10.0) lib/carrierwave/mount.rb:163:in `export='
  carrierwave (0.10.0) lib/carrierwave/orm/activerecord.rb:39:in `export='
  app/controllers/exports_controller.rb:17:in `upload'

(我用的是carrierwave来存储文件)

我认为我没有正确处理 stringIO 但老实说我不知道​​我应该如何将它传递给 post 请求以便它的行为像一个文件

有什么想法吗?

事实证明这是因为我没有将 zip 保存为文件而是使用了 write_buffer 来响应 stringIO。

stringIO read 方法 returns 上传到我的控制器的字符串,然后我尝试使用 carrierwave 大致像这样保存文件:

... code in my controller
myObject = ObjectModel.find(params[:id])
myObject.fileUploader = StringIO.new(params[:file]) => this was the string i received from stringIO read method
myObject.save

但它不会工作,因为自 Rails3 以来 StringIO 对象不再有 original_filename 方法(据我从 carrierwave 问题页面了解)

解决方案是在 StringIO 周围创建一个包装器,并在正确保存文件后添加一个名为 original_filename 的属性或方法。

我将 link 发布到处理此问题的载波维基:

https://github.com/carrierwaveuploader/carrierwave/wiki/How-to:-Upload-from-a-string-in-Rails-3-or-later

和像对象这样的示例包装器

  class StringIOWrapper < StringIO
    attr_accessor :original_filename
  end

之后这将起作用

myObject.fileUploader = StringIOWrapper.new(params[:file])
myObject.save