2014-01-02 7 views
1

У меня есть 1000 + JSON-файлы, которые выглядят какИтеративно разбора JSON файл

{ 
    "name": "Some name", 
    "part_num": "123456", 

    "other_config": { 
     // Large amount of objects 
    }, 
    "some more": { 
     // Large amount of objects 
    } 
    // etc 
} 

Когда моя программа запускается, он должен сканировать директорию со всеми этими JSON файлов, загружать каждый из них, и извлечь "name" и "part_num" и заполняет список с этими значениями. Затем пользователь выбирает один, и этот конфиг затем повторно обрабатывается и предпринимаются соответствующие действия.

Проблема заключается в том, что многие файлы занимают некоторое время. Я немного смягчил его, используя multiprocessing, чтобы бросить работу по всем доступным ядрам в фоновом режиме, а затем заполнить список, как только это сделано, но я все еще ограничен IO. Поскольку я знаю, что этот код будет работать на компьютерах с более медленными процессорами и жесткими дисками, чем у меня, эта скорость неприемлема.

В среднем случае сценарий состоит в том, что значения, которые мне нужны, находятся в начале файла, но я не могу предположить, что это в худшем случае. Есть ли способ итеративного разбора файла JSON, чтобы я мог быстрее загружать то, что мне нужно из этих файлов?

Я мог бы прибегнуть к регулярному выражению, but I'd really prefer not to.

+0

Или вы можете объединить их в структуру SINGLE jsons, например. массив данных, '[{материал из файла1}, {материал из файла2}, ....]', поэтому вы загружаете только файл SINGLE и анализируете структуру SINGLE js .... или просто используете базу данных –

+0

Не использовать файлы JSON? Почему бы не использовать базу данных 'sqlite' для этих данных, например? Сканирование файлов просто * один раз *, если вам нужно. –

+0

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

ответ

1

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

+0

Похоже, это может быть хорошим решением. Я обновлю вас позже, если это будет соответствовать моим потребностям, и если я смогу полностью понять, как использовать этот проект. – bheklilr

+0

Мне нравится внешний вид проекта, но не похоже, что он будет работать в моем случае. Знаете ли вы о каких-либо других библиотеках, которые могут делать то же самое? – bheklilr

+1

Чтобы ответить, было бы хорошо знать, почему YAJL не сработал для вас. – Krumelur

1

Это напоминало мне об XML в тот же день, когда у нас было три стиля парсеров: основанный на DOM (например, SAX) и менее известный на основе pull (например, StAX). Последние два были более эффективными, поскольку они не требовали загрузки всего файла в память, когда вам нужны только его фрагменты.

К счастью, подобные вещи существуют для JSON. Для Python взгляните на yajl-py, который является оболочкой Python для C-библиотеки Yajl.

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

1

Существует ijson, который выполняет итеративный разбор json в режиме pythonc.

Я думаю, что решение вашей проблемы будет:

import ijson 

f = open('...') 
objects = ijson.items(f, 'other_config.item') 
for part in objects: 
    do_something_with(part) 

Dislaimer Я не использовал эту библиотеку.

Смежные вопросы