我在服务器上有一个大的 CSV 文件,我想分块下载和处理,而不是将整个文件读入内存。经过一番摸索后,我想出了这个:
require open-uri
open("http://example.com/#{LARGE_CSV_FILE}") do |file|
file.each_slice(50_000) do |fifty_thousand_lines|
MyModel.import fifty_thousand_lines.join
end
end
我的理解是open-uri
's#open
将包装 HTTP GET 并返回一个IO
-like 可枚举对象。#each_slice(n)
将一次将 n 行的数组传递给块。然后我加入并处理这些行。
这个导入很好,看着我的 OS X iStat 菜单,看起来 ruby 进程的内存使用并没有失控。但是,看起来我一次下载了所有文件。如果没有内存使用爆炸,这怎么可能?
ruby 是否将其下载到临时文件中,然后逐行从磁盘中读取?我原以为open-uri
会改为限制 HTTP 连接,并且仅在其块完成处理其一批数据时才下载更多数据。
这是下载和处理文件而不将其全部加载到内存中的正确方法吗?