本文主要是介绍记录rapidjson写出json时发生截断问题的处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1.问题
rapidjson性能非常棒,在处理大数据量的情况下性能要远优与cjson,是读写json的最佳选择库之一。该库也是腾讯开源的库,很多国外的库也在使用,如ODA等;
在处理一个大文件,转出json时发生了json被截断的情况,也没有报错,真是一时不知从何下手,那就调试吧~
2.调试
心想着可能是rapidjson的bug,要本着这个目标去发现问题,从被截断的地方开始找寻后面的字符本应该是什么,发现本应写出的字符为float类型变量,其值为"-nan(ind)",嗯~,大概知道原因了,再去rapidjson的writer.h文件中调试,发现如下代码:
bool WriteDouble(double d) {if (internal::Double(d).IsNanOrInf()) {if (!(writeFlags & kWriteNanAndInfFlag))return false;if (internal::Double(d).IsNan()) {PutReserve(*os_, 3);PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');return true;}if (internal::Double(d).Sign()) {PutReserve(*os_, 9);PutUnsafe(*os_, '-');}elsePutReserve(*os_, 8);PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f');PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y');return true;}char buffer[25];char* end = internal::dtoa(d, buffer, maxDecimalPlaces_);PutReserve(*os_, static_cast<size_t>(end - buffer));for (char* p = buffer; p != end; ++p)PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p));return true;}
大家注意第2行和第3行:
第2行:如果要写出的double值为非数值或无穷大,要进行第3行的处理;
第3行:如果writeFlags位与kWriteNanAndInfFlag为0,则直接返回false,后续不再继续写,
其中writeFlags默认为kWriteNoFlags(0),kWriteNanAndInfFlag值为2,它俩位与为00 & 10 = 00,这就解释了为什么发生写json时被截断的问题了,其实也不是写json时被截断,是在构造json string内容时就被截断了。
3.解决
我们继续来看该怎么样设置writeFlags值。
writeFlags是模板类Writer的默认参数,显式指定值为kWriteNanAndInfFlag即可,可参考下面文章,
rapidjson::Writer<rapidjson::StringBuffer, rapidjson::UTF8<char>, rapidjson::UTF8<char>, rapidjson::CrtAllocator, rapidjson::kWriteNanAndInfFlag> writer(stringBuffer);
C++:默认模版参数_c++ 类模板 默认参数-CSDN博客
问题解决,
当浮点值为"-nan(ind)"时仍然写出了json。
欢迎交流:公众号:geometrylib
这篇关于记录rapidjson写出json时发生截断问题的处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!