Ранее в этом году, выполняя консультационную работу, мне потребовалось проанализировать файлы JSON, загруженные с URL-адреса в C++. Эту задачу легко выполнить на большинстве языков, многие из которых имеют встроенные библиотеки для чтения и записи файлов JSON (например, пакет json в Python). Однако в случае с C++, как и в большинстве случаев в C++, нет встроенных функций для работы с файлами JSON или строками в формате JSON. Существует одна популярная библиотека, которую используют многие люди, но я обнаружил, что она на самом деле довольно медленная по сравнению с другой библиотекой, RapidJSON, при работе с большими файлами JSON (например, при чтении ~9 лет данные тикера OHLC в JsonCpp заняли ~ 20 минут и всего несколько секунд с RapidJSON).

Хотя документация по RapidJSON очень хорошая, я подумал, что было бы полезно посмотреть пример программирования по обработке JSON-файла на C++. В этом посте я представлю общий способ чтения файла JSON (или строки) в объект документа RapidJSON, а также приведу пример этого из проекта, над которым я сейчас работаю.

RapidJSON

RapidJSON — это библиотека, предназначенная для обеспечения быстрого анализа и создания файлов JSON на C++. Библиотека может быть включена в проект C++ одним из двух способов: реализация только заголовка может быть скопирована в исходный каталог вашего проекта или CMAKE может быть использован для установки проекта, который затем может быть связан с g++ через -lrapidjson . Любой метод приводит к одинаковому использованию, меняется только сборка проекта и включение библиотеки. Более подробную информацию можно найти на GitHub проекта.

Класс Document в RapidJSON содержит содержимое файла JSON в правильной структуре, что позволяет анализировать данные JSON. Класс включен следующим образом

Отсюда очень просто прочитать содержимое файла JSON. Приведенный ниже класс JsonParser можно использовать для анализа файла JSON с помощью функции getJsonDocument(…), которая возвращает объект rapidjson::Document.

В качестве примера я буду использовать файл JSON из проекта, над которым я сейчас работаю. Это очень простой файл JSON без массивов, но он представляет собой базовый пример использования.

Приведенный выше JSON представляет собой некоторые параметры решателя Lattice Boltzmann для гидродинамики. Это можно проанализировать, расширив класс JsonParser выше.

Массивы

Поскольку большинство файлов JSON имеют вложенные структуры массивов, еще одной важной операцией с файлами JSON является повторение массивов JSON. Хотя в настоящее время я не делаю этого в проекте, о котором упоминал выше (скоро буду), я сделал это в консалтинговом проекте, упомянутом ранее в посте. Ниже приведен фрагмент из этой кодовой базы, демонстрирующий итерацию массива JSON в RapidJSON.

Как видно из приведенного выше фрагмента кода, объект документа RapidJSON имеет метод GetArray(), который возвращает объект RapidJSON Value, содержащий данные JSON. Для пояснения: весь проанализированный JSON в RapidJSON хранится в объекте Value. Объект Document — это объект, который представляет DOM и содержит корневое значение дерева DOM.

Заключение

В этом посте был представлен API парсинга JSON RapidJSON. Были показаны и объяснены некоторые примеры использования, представленные в виде фрагментов кода из двух разных проектов, над которыми я работал. Для тех, кому нужна более подробная информация о RapidJSON, у проекта есть очень информативный репозиторий GitHub и еще более информативная документация. Цель этого поста состояла в том, чтобы познакомить с этим проектом тех, кто не знает о его существовании (поскольку я думаю, что большинство людей придерживаются JsonCpp), и предоставить очень примитивное использование, чтобы вы могли начать использовать проект.