记录rapidjson写出json时发生截断问题的处理

18 篇文章 2 订阅

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_, '-');
            }
            else
                PutReserve(*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。

问题解决了?还没有,请继续看下,为什么rapidjson库在浮点型值为nan时默认没有写出json?且也没有报错,是因为rapidjson不严谨吗?

json格式明确规定对于浮点类型不支持+/-Inf、NaN值,所以还需要从源头上排查为什么出现了这些值,并进行处理。

当然为了方便排查问题(let it crash),写出json时仍然可以允许写出+/-Inf、NaN,在发生问题时,充分的暴露问题,以便更好的解决问题。

JSON 数据类型_json穿数值类型-CSDN博客

4.总结

涉及到的知识点:RapidJson库、C++模板类(默认参数)、Json格式规范、位运算等。

欢迎交流:公众号:geometrylib

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值