4

我在 Linux 上运行的基于 QT 的单线程控制台应用程序使用 Boost 解析 JSON 字符串,并且它正常工作,除非接收到非常大的 JSON 块。我有一个大小约为 160kb 的有效 JSON(!),当我尝试解析它时,对 Boost 的 JSON 解析器的调用永远不会返回。我已经离开了很长一段时间。如果我随后中断使用调试器,我的应用程序就会闲置在它的消息循环中,就好像什么都没发生一样。该调用不会引发异常。除了它的大尺寸之外,JSON 没有什么值得注意的——它格式正确并且完全由 ASCII 字符组成。

执行如何简单地“放弃”并返回 QT 消息循环?

void IncomingRequestHandler::OnRequest(const QString& message)
{
    try
    {
        std::stringstream ss;
        ss << message.toStdString();
        boost::property_tree::ptree requestObject;

        cout << "Before read_json" << endl;  // Gets here
        boost::property_tree::json_parser::read_json(ss, requestObject);
        cout << "After read_json" << endl;  // Never gets here

        // ... Some other code ...
    }
    catch (const boost::property_tree::json_parser::json_parser_error& e)
    {
        cout << "Invalid JSON" << endl;  // Never gets here
    }
    catch (const std::runtime_error& e)
    {
        cout << "Invalid JSON" << endl;  // Never gets here
    }
    catch (...)
    {
        cout << "Invalid JSON" << endl;  // Never gets here
    }
}
4

1 回答 1

2

首先,我同意上面的两条评论:尽量减少你的程序。

其次,我会尝试检查 Qt(stl,boost,这个特定版本的任何东西)是否可以处理那么大的字符串。确保您的解析器正在获取整个字符串。

第三,我会使用 ostringstream 而不是 sstream。:)

根据 boost 文档,解析器返回错误的唯一方法似乎是在您的 property_tree 中返回错误信息。如果它一直持续读取,则可能意味着它正在读取超出实际 JSON 数据的垃圾并卡在上面。

最后,read_json 可以接受文件名,那么为什么还要费心读取文件和创建流呢?你为什么不试试这个:

    boost::property_tree::ptree requestObject;
    cout << "Before read_json" << endl;  // Gets here
    boost::property_tree::json_parser::read_json(jsonFileName.toStdString(),
                                                 requestObject);
    cout << "After read_json" << endl;  // Never gets here

我刚刚用 400Kb 大的 JSON 文件进行了一个小测试,它工作得很好:

    #include <iostream> 
    #include <string> 
    #include <boost/property_tree/ptree.hpp>
    #include <boost/property_tree/json_parser.hpp>

    using namespace std;

    int main(int argc, char* argv[])
    {
        string infname = argv[1];

        boost::property_tree::ptree requestObject;
        cout << "Before read_json" << endl;  // Gets here
        boost::property_tree::json_parser::read_json(infname, requestObject);
        cout << "After read_json" << endl;  // Works fine

        return 0;
    }
于 2012-06-23T21:05:50.303 回答