Поскольку вы сказали, что не хотите загружать его в память сразу, возможно, для вас это более удобно.Вы можете установить yajl-ffi gem для достижения этой цели.Из их документации:
Для больших документов мы можем использовать объект ввода-вывода для его потоковой передачи в анализатор.Нам все еще нужно место для анализируемого объекта, но сам документ никогда полностью не читается в память.
require 'yajl/ffi'
stream = File.open('/tmp/test.json')
obj = Yajl::FFI::Parser.parse(stream)
Однако при потоковой передаче небольших документов с диска или по сети гем yajl-ruby
выдастнам лучшая производительность.
Огромные документы, поступающие по сети небольшими порциями в цикл EventMachine
receive_data, - это то место, где Yajl::FFI
уникально подходит.Внутри подкласса EventMachine::Connection
мы можем иметь:
def post_init
@parser = Yajl::FFI::Parser.new
@parser.start_document { puts "start document" }
@parser.end_document { puts "end document" }
@parser.start_object { puts "start object" }
@parser.end_object { puts "end object" }
@parser.start_array { puts "start array" }
@parser.end_array { puts "end array" }
@parser.key { |k| puts "key: #{k}" }
@parser.value { |v| puts "value: #{v}" }
end
def receive_data(data)
begin
@parser << data
rescue Yajl::FFI::ParserError => e
close_connection
end
end
Анализатор принимает фрагменты документа JSON и анализирует до конца доступного буфера.Передача дополнительных данных возобновляет анализ из предыдущего состояния.Когда происходит интересное изменение состояния, анализатор уведомляет все зарегистрированные процессы обратного вызова о событии.
Обратный вызов события - это место, где мы можем выполнять интересную фильтрацию данных и передавать их другим процессам.Приведенный выше пример просто печатает изменения состояния, но обратные вызовы могут искать массив с именами строк и обрабатывать наборы этих объектов строк небольшими партиями.Таким образом, миллионы строк, передаваемых по сети, могут обрабатываться в постоянном пространстве памяти.