部门的产品使用自己公司研发的系统,嵌入式web服务器移植的是goahead2.5的,服务器和前端使用JSON交互,移植的cJSON库,所以这段时间对JSON的使用做个简单的笔记,cJSON.h提供出来的接口很多,但是感觉平时使用的也就那么几个。

  在做测试的时候,通过创建json对象,添加节点,然后保存,读取,输出这样的一个流程,发现当添加节点数多的时候,会会出现长时间的等待,当时好像是一万行的数据量,整个创建过程花费了2,3秒钟,所以当更多数据量的时候,花费的时间可能更长。最后发现是这个函数导致的结果,源码如下,可以看到它每添加一个item,都是从头往后找,等找到最后一个节点的时候,然后把item赋值给最后一个节点的next,所以节点越多,时间也就更长了。

void   cJSON_AddItemToArray(cJSON *array, cJSON *item)

void   cJSON_AddItemToArray(cJSON *array, cJSON *item)
{
cJSON *c=array->child;
if (!item) return;
if (!c)
{
array->child=item;
}
else
{
while (c && c->next)
c=c->next;
suffix_object(c,item);
}
}

  查看cJSON的结构体,会发现,json结构有next和pre两个指针,也就是它的链表是个双向链表,但是就奇怪为何找节点却不用这个优点,非得单向去找。

typedef struct cJSON {
struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ int type; /* The type of the item, as above. */ char *valuestring; /* The item's string, if type==cJSON_String */
int valueint; /* The item's number, if type==cJSON_Number */
double valuedouble; /* The item's number, if type==cJSON_Number */ char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} cJSON;

  所以解决的思路就在这了,有两种方式解决:

  1,利用array的pre指针,每次插入item后,同时将其指针保存在array->child->pre中,这样我每次插入节点,都只需要找到第一个节点的pre指针,然后将item插到该地址之后,即可。

  cJSON * c = array->child;
if(!item)
{
return ;
}
if(!c)
{
array->child = item;
array->child->prev = item;
}
else
{
array->child->prev->next = item;
array->child->prev = item;
item->next = NULL;
  }

  2,第二种方式就很简单,通过修改json结构体实现目的,在结构体中添加一个成员 struct cJSON * last;每次添加item的时候,同时将它的指针赋值给array->child->last;

这样每次添加的时候,只需要查找last指针就可以找到最后一个节点。

  cJSON * c = array->child;
if(!item)
{
return ;
}
if(!c)
{
array->child = item;
array->child->last = item;
}
else
{
array->child->last->next = item;
array->child->last = item;
item = NULL;
}

  用的最多的object对象就是这些了。

#define cJSON_AddNullToObject(object,name) 
#define cJSON_AddTrueToObject(object,name) 
#define cJSON_AddFalseToObject(object,name) 
#define cJSON_AddBoolToObject(object,name,b)
#define cJSON_AddNumberToObject(object,name,n) 
#define cJSON_AddStringToObject(object,name,s)

还有数组对象

void cJSON_AddItemToArray(cJSON *array, cJSON *item);
void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);

如果是将一个数组添加进对象就可以用

void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);

void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);

当用完json对象时候,就必须记者删除

cJSON_Delete(cJSON*);

将一个字符串解析成json对象

extern cJSON *cJSON_Parse(const char *value);

将一个json对象转换成char *,但是这个字符串必须是手动删除

extern char  *cJSON_Print(cJSON *item);

cJSON 库的使用和优化的更多相关文章

  1. [置顶] cJSON库(构建json与解析json字符串)-c语言

     一.c语言获取json中的数据. 1.先要有cJOSN库,两个文件分别是cJSON.c和cJSON.h. 2.感性认识 char * json = "{ \"json\" ...

  2. 【源码分析】cJSON库学习

    cJSON库是什么? cJSON是一个轻量级的json解析库.使用起来非常简单,整个库非常地简洁,核心功能的实现都在cJSON.c文件,非常适合阅读源代码来学习C语言.最近读完这个库的源码,分享自己收 ...

  3. 使用CJSON库实现XML与JSON格式的相互转化

    之前完成了一个两个平台对接的项目.由于这两个平台一个是使用json格式的数据,一个是使用xml格式的数据,要实现它们二者的对接就涉及到这两个数据格式的转化,在查阅相关资料的时候发现了这个CJSON库, ...

  4. cJSON库的简单介绍及使用

    转载:http://www.cnblogs.com/liunianshiwei/p/6087596.html JSON 语法是 JavaScript 对象表示法语法的子集.数据在键/值对中:数据由逗号 ...

  5. 使用cJSON库解析JSON

    cJSON库的下载 cJSON是一个基于C的JSON解析库,这个库非常简单,只有cJSON.c和cJSON.h两个文件,支持JSON的解析和封装,需要调用时,只需要#include "cJS ...

  6. cjson库

    - 源码方式引用,只有两个文件- 标准C89编写 - [cJSON 库项目地址](https://github.com/DaveGamble/cJSON)

  7. C语言cJSON库的使用,解析json数据格式

    C语言cJSON库的使用,解析json数据格式 摘自:https://www.cnblogs.com/piaoyang/p/9274925.html 对于c语言来说是没有字典这样的结构的,所以对于解析 ...

  8. cJSON库源码分析

    本文采用以下协议进行授权: 自由转载-非衍生-保持署名|Creative Commons BY-NC-ND 3.0 ,转载请注明作者及出处. cJSON是一个超轻巧,携带方便,单文件,简单的可以作为A ...

  9. 使用cJSON库解析和构建JSON字符串

    使用cJSON库解析和构建JSON字符串 前言 其实之前的两篇博文已经介绍了json格式和如何使用cJSON库来解析JSON: 使用cJSON库解析JSON JSON简介 当时在MCU平台上使用时,会 ...

随机推荐

  1. AppDelegate减负之常用三方封装 - 友盟推送篇

    之前分享过集成友盟推送的方法, 需要的朋友可以查看一下链接: http://www.cnblogs.com/zhouxihi/p/6533058.html 一般开发中我们比较多使用的三方有友盟推送, ...

  2. Vijos 1004 伊甸园日历游戏 博弈

    描述 Adam和Eve玩一个游戏,他们先从1900.1.1到2001.11.4这个日期之间随意抽取一个日期出来.然后他们轮流对这个日期进行操作: 1 : 把日期的天数加1,例如1900.1.1变到19 ...

  3. python - bilibili(四)抓包数据乱码

    上一篇文章中不知道大家发现端倪木有,两张照片对比很明显发现第一张是信息很明显的,第二张是乱码的. 为什么会出现这种情况?细心的童鞋可能发现是我们发送给服务器的请求连接的数据不同: 第一张图的信息是{& ...

  4. PHP运算符知识点

    表达式 几乎所写的任何东西都是一个表达式,简单却最精确的定义一个表达式的方式就是"任何有值的东西". 算术运算符 Php中常用的有:+.-.*./.%(取模,得到余数) 左+ - ...

  5. Android之IPC(aidl)

    IPC(Inter-Process Conmunication) 进程间通讯 在同一进程中,各个组件进行通信是十分方便的,普通的函数调用就可以解决:但是,对于处于不同进程中的组件来说,要进行通信,就需 ...

  6. c++调用python系列(1): 结构体作为入参及返回结构体

    最近在打算用python作测试用例以便对游戏服务器进行功能测试以及压力测试; 因为服务器是用c++写的,采用的TCP协议,当前的架构是打算用python构造结构体,传送给c++层进行socket发送给 ...

  7. web开发之负载均衡的简单架构

    负载均衡 负载均衡的核心思想就是:请求分担 最简单的配置: 一台负载均衡服务器 两台webserver服务器 两台webserver服务器需要配置相同的服务器环境,设置相同的域名指向 负载均衡服务器需 ...

  8. [C++ Calculator 项目] 文件读入与可视化实现

    Calculator V1.1 注:这是C++计算器项目第三.四部分-文件读写与可视化 [基于原代码重构而得] 源文件已上传至Github 文件读写 可视化 文件读写: Ⅰ.在原基础代码上增加了-f参 ...

  9. 初学安卓开发随笔之 Intent 用法

    首先,对于安卓开发,目前世界上流行的是使用的是Android studio 2.0 .(hh 学着来呗 书上说用这个,,) 今后就定一个计划 每天更新一个Android 随笔,增强一下自控力吧!!! ...

  10. 【CSS】伪类与伪元素

    一伪类 语法: selector : pseudo-class {property: value} 提示:伪类名称对大小写不敏感.    与 CSS类搭配使用 selector.class : pse ...