我在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
}
}
首先,我同意上面的两条评论:尽量最小化你的程序。
其次,我会尝试检查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
我刚刚用 JSON 文件 400Kb 大进行了一个小测试,它工作得很好:
#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;
}