Як розібрати jsonlines за допомогою boost::json (мінімальний приклад)

Наступний приклад показує, як розібрати файл jsonlines за допомогою boost::json. Оскільки файл jsonlines — це просто послідовність рядків, кожен з одним JSON-об’єктом, ми можемо використовувати функцію boost::json::parse для розбору кожного рядка без будь-яких спеціальних дій.

Цей код може розібрати файл jsonlines розміром 4,5 ГБ із 4442720 рядків за 42 секунди на моєму настільному комп’ютері i7-6700 (вивід було вимкнено для цього тесту продуктивності).

jsonlines_parser.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <boost/json.hpp>

class JSONLineProcessor {
public:
    JSONLineProcessor(const std::string& filename) : file(filename) {
        if (!file.is_open()) {
            throw std::runtime_error("Помилка: не вдалося відкрити файл.");
        }
    }

    void process_lines() {
        std::string line;
        while (std::getline(file, line)) {
            process_line(line);
        }
    }

private:
    std::ifstream file;

    void process_line(const std::string& line) {
        try {
            // Розібрати рядок JSON
            boost::json::value json_value = boost::json::parse(line);

            // Перевірити, чи це JSON-об'єкт
            if (json_value.is_object()) {
                process_json(json_value.as_object());
            } else {
                std::cerr << "Помилка: розібране значення не є JSON-об'єктом." << std::endl;
            }
        } catch (const boost::json::system_error& e) {
            // Обробити помилки розбору
            std::cerr << "Помилка розбору рядка JSON: " << e.what() << std::endl;
        }
    }

    void process_json(const boost::json::object& obj) {
        // Для прикладу просто вивести JSON-об'єкт
        std::cout << "Обробка JSON-об'єкта: " << boost::json::serialize(obj) << std::endl;
    }
};

int main(int argc, char** argv) {
    if(argc <= 1) {
        std::cerr << "Використання: " << argv[0] << std::endl;
        return 1;
    }

    try {
        JSONLineProcessor processor(argv[1]);
        processor.process_lines();
    } catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
        return 1;
    }

    return 0;
}

Скомпілюйте так:

compile_jsonlines_parser.sh
g++ -std=c++17 -march=native -O3 -o jsonlines_parser jsonlines_parser.cpp -lboost_json

-march=native та -O3 є необов’язковими, але вони можуть прискорити процес розбору. Зверніть увагу, що -march=native зробить бінарний файл непереносним, оскільки він скомпільований для запуску на процесорах з тією ж архітектурою, що й та, на якій ви компілюєте. Див. документацію -march для отримання додаткової інформації.


Дивіться схожі статті за категоріями: Boost C/C++