ban*_*ing 2 ruby csv ruby-on-rails
我有一个rails应用程序,允许用户上传csv文件,并在delayed_job gem的帮助下安排读取多个csv文件.问题是应用程序将其文件中的每个文件读入内存,然后写入数据库.如果只读取其中的1个文件,但是当读取多个文件时,服务器上的RAM会变满并导致应用程序挂起.
我试图找到解决这个问题的方法.
我研究的一个解决方案是将csv文件分成更小的部分并将它们保存在服务器上,并读取较小的文件.看到这个链接
example: split -b 40k myfile segment
Run Code Online (Sandbox Code Playgroud)
不是我的首选解决方案 有没有其他方法来解决这个问题,我不必破坏文件.解决方案必须是ruby代码.
谢谢,
您可以使用CSV.foreach只读取CSV文件的块:
path = Rails.root.join('data/uploads/.../upload.csv') # or, whatever
CSV.foreach(path) do |row|
# process row[i] here
end
Run Code Online (Sandbox Code Playgroud)
如果它在后台作业中运行,则可以另外调用GC.start每n行.
CSV.foreach 在IO流上运行,如下所示:
def IO.foreach(path, options = Hash.new, &block)
# ...
open(path, options) do |csv|
csv.each(&block)
end
end
Run Code Online (Sandbox Code Playgroud)
该csv.each部分是对IO#each的调用,它逐行读取文件(rb_io_getline_1invokation)并使读取的行被垃圾收集:
static VALUE
rb_io_each_line(int argc, VALUE *argv, VALUE io)
{
// ...
while (!NIL_P(str = rb_io_getline_1(rs, limit, io))) {
rb_yield(str);
}
// ...
}
Run Code Online (Sandbox Code Playgroud)