我有一个Rails应用程序,我正在解析上传的CSV。我刚刚发现解析已停止工作并正在调查。
我已将其追溯到我在.read
的实例上调用ActionDispatch::Http::UploadedFile
并返回空字符串的事实。
上传的文件不为空,当我检查UploadedFile
对象时,它有一个像@tempfile=#<File:/tmp/RackMultipart20130530-34976-6jaqt5
这样的属性。如果我cat
该文件系统上的文件,它包含我期望的内容。
为什么.read
会返回一个空字符串?
我正在使用Rails 3.2.13。
答案 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!