ActionDispatch :: Http :: UploadedFile #read返回空字符串

时间:2013-05-30 15:50:27

标签: ruby-on-rails ruby-on-rails-3.2

我有一个Rails应用程序,我正在解析上传的CSV。我刚刚发现解析已停止工作并正在调查。

我已将其追溯到我在.read的实例上调用ActionDispatch::Http::UploadedFile并返回空字符串的事实。

上传的文件不为空,当我检查UploadedFile对象时,它有一个像@tempfile=#<File:/tmp/RackMultipart20130530-34976-6jaqt5这样的属性。如果我cat该文件系统上的文件,它包含我期望的内容。

为什么.read会返回一个空字符串?

我正在使用Rails 3.2.13。

2 个答案:

答案 0 :(得分:8)

尝试倒带

我的同事建议在rewind之前致电read,这样可行。显然其他一些代码正在首先读取文件。

更新

据我所知,没有人在我之前阅读文件。我创建了一个初始化程序来监视UploadedFile

# config/initializers/uploaded_file.rb
class ActionDispatch::Http::UploadedFile

  alias_method :old_read, :read
  def read(*args)
    Rails.logger.info "file #{self} is getting read by #{caller.first}!"
    old_read(*args)
  end
end

我没有看到对read的任何其他调用。认为可能有一些其他方法被称为推进读指针,我进一步完全取代了类:

# config/initializers/uploaded_file.rb
ActionDispatch::Http::UploadedFile = Class.new do

  def initialize(*args)
    Rails.logger.info "initilized with #{args}"
  end

  def method_missing(method_name, *args, &block)
    Rails.logger.info "file got #{method_name} with #{args}.\
      Block? #{block_given?} caller? #{caller.first}"
  end

end

仍然没有。我看到了initialize的来电,我对rewind的来电以及我对read的来电。

好像这个文件预先缠绕到最后。我不确定为什么会这样,但rewind仍然是我的修复。

答案 1 :(得分:0)

如果文件刚刚上传和写入,请务必在继续之前将其关闭。例如:

out = File.open(path, 'w')
out.write(stuff)
out.close # omitting this may cause the issue described!