【问题标题】:How do I get a Ruby IO stream for a Paperclip Attachment?如何获取回形针附件的 Ruby IO 流?
【发布时间】:2016-02-01 21:53:22
【问题描述】:

我有一个使用 Paperclip gem 存储上传的 CSV 文件的应用程序。

上传后,我希望能够将上传文件中的数据流式传输到代码中,该代码逐行读取数据并将其加载到 Postgres 中的数据暂存表中。

我的努力已经走到了这一步,data_file.upload 是一个回形针 CSV 附件

io = StringIO.new(Paperclip.io_adapters.for(data_file.upload).read, 'r')

尽管 ^^ 有效,但问题是 - 如您所见 - 它将整个文件作为 honkin' Ruby 字符串加载到内存中,而 Ruby 字符串垃圾对应用程序性能非常不利。

相反,我想要一个支持使用例如 io.gets 的 Ruby IO 对象,以便 IO 对象处理缓冲和清理,并且整个文件不会像一个巨大的字符串一样存在于内存中。

提前感谢您的任何建议!

【问题讨论】:

  • 嗯,Paperclip::AbstractAdapter#read 确实接受 2 个参数,第一个是要读取的字符数,第二个是一些名为 buffer 的神秘字符串......但这并没有真正的帮助,因为什么我真正想做的就是读到下一个换行符。哦,好吧。

标签: ruby-on-rails-4 io paperclip


【解决方案1】:

在一些帮助(当然是来自 StackOverflow)的帮助下,我自己解决了这个问题。

在我的 PaperClip AR 模型对象中,我现在有以下内容:

# Done this way so we get auto-closing of the File object
def yielding_upload_as_readable_file
  # It's quite annoying that there's not 1 method that works for both filesystem and S3 storage
  open(filesystem_storage? ? upload.path : upload.url) { |file| yield file }
end

def filesystem_storage?
  Paperclip::Attachment.default_options[:storage] == :filesystem
end

...而且,我在另一个模型中使用它,如下所示:

data_file.yielding_upload_as_readable_file do |file|
  while line = file.gets
    next if line.strip.size == 0
    ... process line ...
  end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多