Ruby - чтение файла в пакетном режиме - PullRequest
7 голосов
/ 03 июня 2010

Я читаю файл размером 10 МБ, который содержит некоторые идентификаторы. Я прочитал их в список в рубине. Я обеспокоен тем, что это может вызвать проблемы с памятью в будущем, когда число идентификаторов в файле может увеличиться. Есть ли эффективный способ чтения большого файла в пакетном режиме?

Спасибо

Ответы [ 2 ]

19 голосов
/ 10 декабря 2016

С помощью Ленивые счетчики и 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
4 голосов
/ 03 июня 2010

универсального пути нет.

1) Вы можете прочитать файл по частям:

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

недостаток: вы можете пропустить подстроку, если она будет между кусками, то есть вы ищете "SOME_TEXT", но "SOME_" - это последние 5 байтов первого 2048-байтового блока, и ТЕКСТ "4 байта 2-го блока

2) Вы можете читать файл построчно

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

недостаток: таким образом, это будет в 2,5 раза медленнее, чем в первом методе

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...