Разбор большого файла JSON [дубликат]


На этот вопрос уже есть ответ здесь:

Я работаю над скриптом cron, который обращается к API, получает файл JSON (большой массив объектов) и сохраняет его локально. Как только это будет завершено, другой скрипт должен проанализировать загруженный файл JSON и вставить каждый объект в MySQL база данных.

В настоящее время я использую file_get_contents() вместе с json_decode(). Это позволит попытаться прочитать весь файл в память, прежде чем пытаться его обработать. Это было бы прекрасно, за исключением того факта, что мои файлы JSON обычно варьируются от 250 МБ до 1 ГБ+. Я знаю, что могу увеличить свой лимит памяти PHP, но, похоже, это не самый лучший ответ на мой взгляд. Я знаю, что могу запустить fopen() и fgets(), чтобы прочитать файл построчно, но мне нужно прочитать файл по каждому объекту json.

Есть ли способ чтения в файле для каждого объекта или есть другой аналогичный подход?

Author: Ry-, 2013-03-13

3 answers

Это действительно зависит от того, что содержат файлы json.

Если открытие файла одним выстрелом в память не является опцией, ваш единственный другой вариант, как вы ускользнули, - это fopen/fgets.

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

Как только вы соберете весь объект, вы вставите его в базу данных, а затем перейдете к следующему.

Больше в этом ничего нет. алгоритм определения начала и конца объекта json может усложняться в зависимости от вашего источника данных, но я уже делал что-то подобное раньше с гораздо более сложной структурой (xml), и он работал нормально.

 5
Author: Kovo, 2013-03-12 22:36:26

Попробуйте эту библиотеку https://github.com/shevron/ext-jsonreader

Существующий ext/json, поставляемый с PHP, очень удобен и прост в использовании, но он неэффективен при работе с большими количество данных JSON, так как для этого требуется считывать все данные JSON в память (например, с помощью file_get_contents()), а затем сразу преобразовывать их в переменную PHP - для больших наборов данных это занимает много памяти.

JsonReader разработан для экономии памяти - он работает с потоками и может считывать данные JSON из любого потока PHP без загрузки всех данных в память. Это также позволяет разработчику извлекать определенные значения из потока JSON без декодирования и загрузки всех данных в память.

 7
Author: Pawel Dubiel, 2013-03-12 22:54:33

Наилучшее возможное решение:

Используйте какой-либо разделитель (разбивка на страницы, временная метка, идентификатор объекта и т.д.), Который позволяет считывать данные небольшими порциями по нескольким запросам. Это решение предполагает, что у вас есть какой-то контроль над тем, как создаются эти файлы JSON. Я основываю свое предположение на:

Это было бы прекрасно, за исключением того факта, что мои файлы JSON обычно варьируются от 250 МБ до 1 ГБ+.

Считывание и обработка 1 ГБ данных JSON это просто смешно. Определенно необходим лучший подход.

 4
Author: Wayne Whitty, 2013-03-12 22:43:18