Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 可以处理大输入(2GB)的JSON解析器?_C++_C_Json - Fatal编程技术网

C++ 可以处理大输入(2GB)的JSON解析器?

C++ 可以处理大输入(2GB)的JSON解析器?,c++,c,json,C++,C,Json,到目前为止,我已经尝试过(没有成功): –“文档太大”(看起来最大大小被人为地限制在1签出。我用一个大型数据库(SF street data或其他,大约2GB)对其进行了测试。速度相当快。签出。我用一个大型数据库(SF street data或其他,大约2GB)对其进行了测试。速度相当快。好吧,我对我的解决方案并不感到自豪,但我最终使用了一些正则表达式将数据拆分为顶级键值对(每个键值对只有几MB),然后用Qt的JSON解析器解析其中的每一对,并将它们传递到我的原始代码中 Yajl正是我所需要的

到目前为止,我已经尝试过(没有成功):


  • –“文档太大”(看起来最大大小被人为地限制在
    1签出。我用一个大型数据库(SF street data或其他,大约2GB)对其进行了测试。速度相当快。

    签出。我用一个大型数据库(SF street data或其他,大约2GB)对其进行了测试。速度相当快。

    好吧,我对我的解决方案并不感到自豪,但我最终使用了一些正则表达式将数据拆分为顶级键值对(每个键值对只有几MB),然后用Qt的JSON解析器解析其中的每一对,并将它们传递到我的原始代码中

    Yajl正是我所需要的,但我选择了丑陋的正则表达式,因为:

  • 将我的逻辑融入其中需要重写足够多的代码,这是一件痛苦的事情,而这只是为了一个一次性的MapReduce工作,因此代码本身对长期来说并不重要

  • 数据集由我控制,并保证始终与我的正则表达式一起工作

  • 出于各种原因,向弹性MapReduce部署中添加依赖项比它应该做的要麻烦得多(并且静态Qt编译有缺陷),因此为了不做超出必要的工作,我倾向于将依赖项保持在最低限度

  • 这仍然有效,并且性能良好(时间和内存方面)

  • 请注意,我使用的正则表达式恰好适用于我的数据,因为顶级键(只有顶级键)是整数;我下面的代码不是一个通用的解决方案,我不会建议在SAX风格的解析器上使用类似的方法,因为上面的原因1和2不适用

    还要注意的是,这个解决方案是额外的(在解析之前拆分和操作JSON字符串+数据开始和结束的特殊情况),因为捕获整个键值对的原始表达式在其中一个键值对超过(在这种情况下,这甚至是一件事,这令人难以置信地恼火,特别是因为它不能通过QRegularExpression或grep进行配置)


    不管怎样,代码是这样的;我深感惭愧:

    QFile file( argv[1] );
    file.open( QIODevice::ReadOnly );
    QTextStream textStream( &file );
    
    QString jsonKey;
    QString jsonString;
    QRegularExpression jsonRegex( "\"-?\\d+\":" );
    
    bool atEnd = false;
    
    
    while( atEnd == false )
    {
        QString regexMatch  = jsonRegex.match
        (
            jsonString.append( textStream.read(1000000) )
        ).captured();
    
        bool isRegexMatched = regexMatch.isEmpty() == false;
    
        if( isRegexMatched == false )
        {
            atEnd = textStream.atEnd();
        }
    
        if( atEnd || (jsonKey.isEmpty() == false && isRegexMatched) )
        {
            QString jsonObjectString;
    
            if( atEnd == false )
            {
                QStringList regexMatchSplit = jsonString.split( regexMatch );
    
                jsonObjectString = regexMatchSplit[0]
                    .prepend( jsonKey )
                    .prepend( LEFT_BRACE )
                ;
    
                jsonObjectString = jsonObjectString
                    .left( jsonObjectString.size() - 1 )
                    .append( RIGHT_BRACE )
                ;
    
                jsonKey    = regexMatch;
                jsonString = regexMatchSplit[1];
            }
            else
            {
                jsonObjectString = jsonString
                    .prepend( jsonKey )
                    .prepend( LEFT_BRACE )
                ;
            }
    
            QJsonObject jsonObject = QJsonDocument::fromJson
            (
                jsonObjectString.toUtf8()
            ).object();
    
            QString key = jsonObject.keys()[0];
    
    
    
            ... process data and store in boost::interprocess::map ...
    
    
        }
        else if( isRegexMatched )
        {
            jsonKey    = regexMatch;
            jsonString = jsonString.split( regexMatch )[1];
        }
    }
    

    好吧,我对我的解决方案并不感到自豪,但我最终使用一些正则表达式将我的数据拆分为顶级键值对(每个键值对只有几MB),然后用Qt的JSON解析器解析这些键值对中的每一个,并将它们传递到我的原始代码中

    Yajl正是我所需要的,但我选择了丑陋的正则表达式,因为:

  • 将我的逻辑融入其中需要重写足够多的代码,这是一件痛苦的事情,而这只是为了一个一次性的MapReduce工作,因此代码本身对长期来说并不重要

  • 数据集由我控制,并保证始终与我的正则表达式一起工作

  • 出于各种原因,向弹性MapReduce部署中添加依赖项比它应该做的要麻烦得多(并且静态Qt编译有缺陷),因此为了不做超出必要的工作,我倾向于将依赖项保持在最低限度

  • 这仍然有效,并且性能良好(时间和内存方面)

  • 请注意,我使用的正则表达式恰好适用于我的数据,因为顶级键(只有顶级键)是整数;我下面的代码不是一个通用的解决方案,我不会建议在SAX风格的解析器上使用类似的方法,因为上面的原因1和2不适用

    还要注意的是,这个解决方案是额外的(在解析之前拆分和操作JSON字符串+数据开始和结束的特殊情况),因为捕获整个键值对的原始表达式在其中一个键值对超过(在这种情况下,这甚至是一件事,这令人难以置信地恼火,特别是因为它不能通过QRegularExpression或grep进行配置)


    不管怎样,代码是这样的;我深感惭愧:

    QFile file( argv[1] );
    file.open( QIODevice::ReadOnly );
    QTextStream textStream( &file );
    
    QString jsonKey;
    QString jsonString;
    QRegularExpression jsonRegex( "\"-?\\d+\":" );
    
    bool atEnd = false;
    
    
    while( atEnd == false )
    {
        QString regexMatch  = jsonRegex.match
        (
            jsonString.append( textStream.read(1000000) )
        ).captured();
    
        bool isRegexMatched = regexMatch.isEmpty() == false;
    
        if( isRegexMatched == false )
        {
            atEnd = textStream.atEnd();
        }
    
        if( atEnd || (jsonKey.isEmpty() == false && isRegexMatched) )
        {
            QString jsonObjectString;
    
            if( atEnd == false )
            {
                QStringList regexMatchSplit = jsonString.split( regexMatch );
    
                jsonObjectString = regexMatchSplit[0]
                    .prepend( jsonKey )
                    .prepend( LEFT_BRACE )
                ;
    
                jsonObjectString = jsonObjectString
                    .left( jsonObjectString.size() - 1 )
                    .append( RIGHT_BRACE )
                ;
    
                jsonKey    = regexMatch;
                jsonString = regexMatchSplit[1];
            }
            else
            {
                jsonObjectString = jsonString
                    .prepend( jsonKey )
                    .prepend( LEFT_BRACE )
                ;
            }
    
            QJsonObject jsonObject = QJsonDocument::fromJson
            (
                jsonObjectString.toUtf8()
            ).object();
    
            QString key = jsonObject.keys()[0];
    
    
    
            ... process data and store in boost::interprocess::map ...
    
    
        }
        else if( isRegexMatched )
        {
            jsonKey    = regexMatch;
            jsonString = jsonString.split( regexMatch )[1];
        }
    }
    
    我最近完成了这样一个库(可能还有一点测试版):

    https://github.com/matiu2/json--11
    
    如果您使用json_类,它会将所有内容加载到内存中,这可能不是您想要的

    但是您可以通过编写自己的“映射器”来按顺序解析它

    包含的映射器迭代JSON,将输入映射到JSON类:

    https://github.com/matiu2/json--11/blob/master/src/mapper.hpp
    
    您可以编写自己的,对数据做任何您想做的事情,并向其中提供一个文件流,这样就不会将整批数据加载到内存中

    因此,作为一个开始的示例,这只是以某种随机格式输出json数据,但不会填充任何内存(完全未测试或编译):

    #包括“parser.hpp”
    #包括
    #包括
    #包括
    int main(int argc,char**){
    std::ifstream文件(“hugeJSONFile.hpp”);
    std::istream_迭代器输入(文件);
    自动解析器=json::解析器(输入);
    使用Parser=decltype(解析器);
    使用std::cout;
    使用std::endl;
    开关(parser.getNextType()){
    大小写分析器::null:
    parser.readNull();
    cout我最近完成了这样一个库(可能还有点测试版):

    https://github.com/matiu2/json--11
    
    如果您使用json_类,它会将所有内容加载到内存中,这可能不是您想要的

    但是您可以通过编写自己的“映射器”来按顺序解析它

    包含的映射器迭代JSON,将输入映射到JSON类:

    https://github.com/matiu2/json--11/blob/master/src/mapper.hpp
    
    您可以编写自己的,对数据做任何您想做的事情,并向其中提供一个文件流,这样就不会将整批数据加载到内存中

    因此,作为一个开始的示例,这只是以某种随机格式输出json数据,但不会填充任何内存(完全未测试或编译):

    #包括“parser.hpp”
    #包括
    #包括
    #包括
    int main(int argc,char**){
    std::ifstream文件(“hugeJSONFile.hpp”);
    std::istream_迭代器输入(文件);
    自动解析器=json::解析器(输入);
    使用Parser=decltype(pars