Ruby - 批量读取文件

时间:2010-06-02 22:41:59

标签: ruby-on-rails ruby scripting

我正在读一个大小为10mb的文件,其中包含一些id。我把它们读成红宝石列表。我担心将来可能会导致内存问题,因为文件中的id数量可能会增加。是否有批量读取大文件的有效方法?

谢谢

3 个答案:

答案 0 :(得分:19)

使用Lazy Enumeratorseach_slice,您可以充分利用这两个方面。您不必担心在中间切割线,您可以批量迭代多行。 batch_size可以自由选择。

header_lines = 1
batch_size   = 2000

File.open("big_file") do |file|
  file.lazy.drop(header_lines).each_slice(batch_size) do |lines|
    # do something with batch of lines
  end
end

它可用于将巨大的CSV文件导入数据库:

require 'csv'
batch_size   = 2000

File.open("big_data.csv") do |file|
  headers = file.first
  file.lazy.each_slice(batch_size) do |lines|
    csv_rows = CSV.parse(lines.join, write_headers: true, headers: headers)
    # do something with 2000 csv rows, e.g. bulk insert them into a database
  end
end

答案 1 :(得分:4)

没有普遍的方式。

1)你可以通过块读取文件:

File.open('filename','r') do |f|
  chunk = f.read(2048)
  ...
end

缺点:如果它位于块之间,你可能会错过一个子串,即你寻找“SOME_TEXT”,但是“SOME_”是第一个2048字节块的最后5个字节,并且“TEXT”是4字节的第二块

2)你可以逐行阅读文件

File.open('filename','r') do |f|
  line = f.gets
  ...
end

缺点:这种方式比第一种方法慢2x..5x

答案 2 :(得分:-1)

如果您非常担心速度/内存效率,您是否考虑过使用 shell 并使用 grepawksed 等?如果我对输入文件的结构以及您要提取的内容有更多了解,我可能会为您构建一个命令。