Как правильно проанализировать очень большой файл JSON в Ruby? - PullRequest
0 голосов
/ 18 октября 2018

Как мы можем проанализировать файл json в Ruby?

require 'json'

JSON.parse File.read('data.json')

Что если файл очень большой и мы не хотим загружать его в память сразу?Как бы мы это проанализировали?

Ответы [ 3 ]

0 голосов
/ 18 октября 2018

Поскольку вы сказали, что не хотите загружать его в память сразу, возможно, для вас это более удобно.Вы можете установить 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 и анализирует до конца доступного буфера.Передача дополнительных данных возобновляет анализ из предыдущего состояния.Когда происходит интересное изменение состояния, анализатор уведомляет все зарегистрированные процессы обратного вызова о событии.

Обратный вызов события - это место, где мы можем выполнять интересную фильтрацию данных и передавать их другим процессам.Приведенный выше пример просто печатает изменения состояния, но обратные вызовы могут искать массив с именами строк и обрабатывать наборы этих объектов строк небольшими партиями.Таким образом, миллионы строк, передаваемых по сети, могут обрабатываться в постоянном пространстве памяти.

0 голосов
/ 03 июля 2019

Не совсем «правильный» способ сделать что-то, но вы могли бы вместо этого использовать команду linux jq.Это самый эффективный анализатор json, который я когда-либо видел.

result = %x{jq -r '.foo | .bar' #{input_json_file}}.strip

0 голосов
/ 18 октября 2018

Вы можете использовать oj gem

Обеспечивает эффективный Oj::Saj синтаксический анализатор.

Документация здесь: http://www.ohler.com/oj/doc/Oj/Saj.html

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