代码之家  ›  专栏  ›  技术社区  ›  Boolean

Ruby-批量读取文件

  •  6
  • Boolean  · 技术社区  · 14 年前

    我正在读取一个大小为10MB的文件,其中包含一些ID。我用Ruby将它们读取到一个列表中。我担心在将来,当文件中的ID数量可能增加时,它可能会导致内存问题。是否有一种批量读取大文件的有效方法?

    谢谢你

    2 回复  |  直到 14 年前
        1
  •  4
  •   zed_0xff    14 年前

    没有普遍的方法。

    1)可以分块读取文件:

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

    缺点: 如果子字符串位于块之间,则可能会丢失子字符串,即查找“some_text”,但“some_u”是第1个2048字节块的最后5个字节,“text”是第2个块的4个字节。

    2)可以逐行读取文件

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

    缺点: 这样比第一种方法慢2到5倍

        2
  •  16
  •   Eric Duminil    8 年前

    Lazy Enumerators each_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