[序列化协议] --- JSON

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: [序列化协议] --- JSON

1. json的基础语法和规范

1.1 json是什么

- JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)
- JSON 是轻量级的文本数据交换格式
- JSON 独立于语言:JSON 使用 Javascript语法来描述数据对象,但是 JSON 仍然独立于语言和平台。JSON 解析器和 JSON 库支持许多不同的编程语言。 目前非常多的动态(PHP,JSP,.NET)编程语言都支持JSON。
- JSON 具有自我描述性,更易理解

1.2 JSON基本语法规则

  • 数据在名称/值对中
  • 数据由逗号分隔
  • 大括号 {} 保存对象
  • 中括号 [] 保存数组,数组可以包含多个对象

JSON的值可以是:

  • 数字(整数或浮点数)
  • 字符串(在双引号中)
  • 逻辑值(true 或 false)
  • 数组(在中括号中)
  • 对象(在大括号中)
  • null

给出一个简单的JSON格式文件示例

{
    "sites": [
        { "name":"菜鸟教程" , "url":"www.runoob.com" }, 
        { "name":"google" , "url":"www.google.com" }, 
        { "name":"微博" , "url":"www.weibo.com" }
    ],
    "flag" : true
}

2. 使用JSONcpp开源库解析JSON文件

2.1 jsoncpp源码下载

直接在github搜索jsoncpp即可。给出下载连接:https://github.com/open-source-parsers/jsoncpp

2.2 具体配置步骤

1> 解压源码

2> 在源码目录的上一层新建build目录,用来保存编译过程生成的中间文件

3> 在build目录执行cmake …

4> 在build目录执行make

5> 在build目录下执行make install

查看安装在本地的jsoncpp库

ls /usr/local/include ls/usr/local/lib

将编译生成的头文件,还有.so文件放在项目中,可以直接使用jsoncpp的库函数。

我这里已经写好了一个示例项目https://github.com/yum9193/json_cpp_usage

3. 关于jsoncpp库的使用简介

使用jsoncpp有两种方法

方法一:使用Jsoncpp生成的lib文件

解压上面下载的Jsoncpp文件,在jsoncpp默认生成静态链接库。 在工程中引用,只需要包含include/json下的头文件及生成的.lib文件即可。

方法二:使用Jsoncpp包中的.cpp和.h文件

解压上面下载的Jsoncpp文件,把jsoncpp-src-0.5.0文件拷贝到工程目录下,将jsoncpp-src-0.5.0\jsoncpp-src-0.5.0\include\json和jsoncpp-src-0.5.0\jsoncpp-src-0.5.0\src\lib_json目录里的文件包含到VS工程中,在VS工程的属性C/C++下General中Additional Include Directories包含头文件目录.\jsoncpp-src-0.5.0\include。在使用的cpp文件中包含json头文件即可,如:#include “json/json.h”。将json_reader.cpp、json_value.cpp和json_writer.cpp三个文件的Precompiled Header属性设置为Not Using Precompiled Headers,否则编译会出现错误。

jsoncpp 使用详解

jsoncpp 主要包含三种类型的 class:Value、Reader、Writer。jsoncpp 中所有对象、类名都在 namespace Json 中,包含 json.h 即可。

Json::Value 只能处理 ANSI 类型的字符串,如果 C++ 程序是用 Unicode 编码的,最好加一个 Adapt 类来适配。

4. 使用c++读取json文件示例

demo.json文件【源码直接抄录自https://blog.csdn.net/shuiyixin/article/details/89330529

{
   "age" : 21,
   "friends" : {
      "friend_age" : 21,
      "friend_name" : "ZhaoWuxian",
      "friend_sex" : "man"
   },
   "hobby" : [ "sing", "run", "Tai Chi" ],
   "name" : "shuiyixin",
   "sex" : "man"
}

test.cpp文件

#include <iostream>
#include <json/json.h>
#include <fstream>
using namespace std;
void readFileJson()
{
        Json::Reader reader;
        Json::Value root;
        //从文件中读取,保证当前文件有demo.json文件  
        ifstream in("demo.json", ios::binary);
        if (!in.is_open())
        {
                cout << "Error opening file\n";
                return;
        }
        if (reader.parse(in, root))
        {
                //读取根节点信息  
                string name = root["name"].asString();
                int age = root["age"].asInt();
                string sex = root["sex"].asString();
                cout << "My name is " << name << endl;
                cout << "I'm " << age << " years old" << endl;
                cout << "I'm a " << sex << endl;
        
        //读取子节点信息  
                string friend_name = root["friends"]["friend_name"].asString();
                int friend_age = root["friends"]["friend_age"].asInt();
                string friend_sex = root["friends"]["friend_sex"].asString();
                cout << "My friend's name is " << friend_name << endl;
                cout << "My friend's sex is "<<friend_sex << endl;
                cout << "My friend is " << friend_age << " years old" << endl;
                //读取数组信息  
                cout << "Here's my hobby:" << endl;
                for (unsigned int i = 0; i < root["hobby"].size(); i++)
                {
                        string ach = root["hobby"][i].asString();
                        cout << ach << '\t';
                }
                cout << endl;
                cout << "Reading Complete!" << endl;
        }
        else
        {
                cout << "parse error\n" << endl;
        }
        in.close();
}
int main(void)
{
        readFileJson();
        return 0;
}

执行结果如下:

5. 使用c++写入json文件示例

test.cpp文件:
#include <iostream>
#include <json/json.h>
#include <fstream>
using namespace std;
void writeFileJson()
{
  //根节点  
  Json::Value root;
 
  //根节点属性  
  root["name"] = Json::Value("shuiyixin");
  root["age"] = Json::Value(21);
  root["sex"] = Json::Value("man");
 
  //子节点  
  Json::Value friends;
 
  //子节点属性  
  friends["friend_name"] = Json::Value("ZhaoWuxian");
  friends["friend_age"] = Json::Value(21);
  friends["friend_sex"] = Json::Value("man");
 
  //子节点挂到根节点上  
  root["friends"] = Json::Value(friends);
 
  //数组形式  
  root["hobby"].append("sing");
  root["hobby"].append("run");
  root["hobby"].append("Tai Chi");
 
  //直接输出  
  //cout << "FastWriter:" << endl;
  //Json::FastWriter fw;
  //cout << fw.write(root) << endl << endl;
 
  //缩进输出  
  cout << "StyledWriter:" << endl;
  Json::StyledWriter sw;
  cout << sw.write(root) << endl << endl;
 
  //输出到文件  
  ofstream os;
  os.open("demo.json", std::ios::out | std::ios::app);
  if (!os.is_open())
    cout << "error:can not find or create the file which named \" demo.json\"." << endl;
  os << sw.write(root);
  os.close();
 
}
int main(void)
{
        writeFileJson();
        return 0;
}

执行结果如下:可以看到已经在目录新建了demo.json文件,并且写入成功

要注意的是:

1.如果要写入的文件不存在,会自动创建该文件;

2.如果文件存在,写入过程不会覆盖文件中原有数据,而是将新数据写在原有数据后面。

6. 解析json样式字符串

在实际项目中更多使用的是从文件解析json,从字符串解析json示例只是为了完整记录。

6.1 简单json样式字符串解析示例

#include <iostream>
#include <json/json.h>
#include <fstream>
using namespace std;
void readStrJson()
{
  //字符串  
  const char* str =
  "{\"name\":\"shuiyixin\",\"age\":\"21\",\"sex\":\"man\"}";
//  "{
//    "name" : "shuiyixin",
//    "age" : "21",
//    "sex" : "man"
//  }";
 
 
  Json::Reader reader;
  Json::Value root;
 
  //从字符串中读取数据  
  if (reader.parse(str, root))
  {
    string name = root["name"].asString();
    int age = root["nomen"].asInt();
    string sex = root["sex"].asString();
    cout << name + "," << age << "," << sex <<  endl;
  }
 
}
int main(void)
{
        readStrJson();
        return 0;
}

执行结果如下:

6.2 复杂json样式字符串解析示例

#include <iostream>
#include <json/json.h>
#include <fstream>
using namespace std;
void readStrProJson()
{
  string strValue = "{\"name\":\"shuiyixin\",\"major\":[{\"AI\":\"MachineLearning\"},{\"AI\":\"DeepLearning\"},{\"AI\":\"ComputerVision\"}]}";
  
  /*
  {
    "name":"shuiyixin",
    "major":[
    {
      "AI":"MachineLearning"
    },
    {
      "AI":"DeepLearning"
    },
    {
      "AI":"ComputerVision"
    }]
  }
  */
  
  
  Json::Reader reader;
  Json::Value value;
  if (reader.parse(strValue, value))
  {
    string out = value["name"].asString();
    cout << out << endl;
    const Json::Value arrayObj = value["major"];
    for (unsigned int i = 0; i < arrayObj.size(); i++)
    {
      out = arrayObj[i]["AI"].asString();
      cout << out<<endl;
    }
  }
}
int main(void)
{
        readStrProJson();
        return 0;
}

执行结果如下:

7. 组装json样式字符串

#include <iostream>
#include <string.h>
using namespace std;
/**
 * 拼接int
 */
std::string  getKeyValue(std::string sKey, int iValue)
{
    char szDoubleQutoes[] = "\"";
    char szColon[] = ":";
    char szValue[50] = { 0 };
    std::string strResult;
    strResult.append("{");
    strResult.append(szDoubleQutoes);
    strResult.append(sKey);
    strResult.append(szDoubleQutoes);
    strResult.append(szColon);
    sprintf(szValue, "%d", iValue);
    strResult.append(szValue);
    strResult.append("}");
    return strResult;
}
/**
 * 拼接float,保留3位
 */
std::string  getKeyValue(std::string sKey, float fValue)
{
    char szDoubleQutoes[] = "\"";
    char szColon[] = ":";
    char szValue[50] = { 0 };
    std::string strResult;
    strResult.append("{");
    strResult.append(szDoubleQutoes);
    strResult.append(sKey);
    strResult.append(szDoubleQutoes);
    strResult.append(szColon);
    sprintf(szValue, "%0.3f", fValue);
    strResult.append(szValue);
    strResult.append("}");
    return strResult;
}
/**
 * 拼接string
 */
std::string  getKeyValue(std::string sKey, std::string sValue)
{
    char szDoubleQutoes[] = "\"";
    char szColon[] = ":";
    std::string strResult;
    strResult.append("{");
    strResult.append(szDoubleQutoes);
    strResult.append(sKey);
    strResult.append(szDoubleQutoes);
    strResult.append(szColon);
    strResult.append(szDoubleQutoes);
    strResult.append(sValue);
    strResult.append(szDoubleQutoes);
    strResult.append("}");
    return strResult;
}
/**
 * 拼接object
 */
std::string  getKeyValueObject(std::string sKey, std::string sObject)
{
    char szDoubleQutoes[] = "\"";
    char szColon[] = ":";
    std::string strResult;
    strResult.append(szDoubleQutoes);
    strResult.append(sKey);
    strResult.append(szDoubleQutoes);
    strResult.append(szColon);
    strResult.append(sObject);
    return strResult;
}
/**
 * 拼接array
 */
std::string  getKeyValueArray(std::string sKey, std::string sArray)
{
    char szDoubleQutoes[] = "\"";
    char szColon[] = ":";
    std::string strResult;
    strResult.append(szDoubleQutoes);
    strResult.append(sKey);
    strResult.append(szDoubleQutoes);
    strResult.append(szColon);
    strResult.append("[");
    strResult.append(sArray);
    strResult.append("]");
    return strResult;
}
struct student
{
  int age;
  char sex[10];
  float score;
};
int main(void)
{
  student s1;
  s1.age = 20; 
  strcpy(s1.sex, "man");
  s1.score = 120.5;
  
  printf("%s\n", getKeyValue("age", s1.age).c_str());
  printf("%s\n", getKeyValue("sex", s1.sex).c_str());
  printf("%s\n", getKeyValue("score", s1.score).c_str());
  
  return 0;
}

编译输出:

参看连接:

https://blog.csdn.net/shuiyixin/article/details/89330529

https://www.cnblogs.com/liaocheng/p/4243731.html

相关文章
|
2月前
|
XML 存储 JSON
Twaver-HTML5基础学习(19)数据容器(2)_数据序列化_XML、Json
本文介绍了Twaver HTML5中的数据序列化,包括XML和JSON格式的序列化与反序列化方法。文章通过示例代码展示了如何将DataBox中的数据序列化为XML和JSON字符串,以及如何从这些字符串中反序列化数据,重建DataBox中的对象。此外,还提到了用户自定义属性的序列化注册方法。
47 1
|
8天前
|
JSON JavaScript Java
对比JSON和Hessian2的序列化格式
通过以上对比分析,希望能够帮助开发者在不同场景下选择最适合的序列化格式,提高系统的整体性能和可维护性。
13 3
|
14天前
|
JSON 数据格式 索引
Python中序列化/反序列化JSON格式的数据
【11月更文挑战第4天】本文介绍了 Python 中使用 `json` 模块进行序列化和反序列化的操作。序列化是指将 Python 对象(如字典、列表)转换为 JSON 字符串,主要使用 `json.dumps` 方法。示例包括基本的字典和列表序列化,以及自定义类的序列化。反序列化则是将 JSON 字符串转换回 Python 对象,使用 `json.loads` 方法。文中还提供了具体的代码示例,展示了如何处理不同类型的 Python 对象。
|
16天前
|
JSON JavaScript 前端开发
|
2月前
|
JSON Go 数据格式
Golang语言结构体链式编程与JSON序列化
这篇文章是关于Go语言中结构体链式编程与JSON序列化的教程,详细介绍了JSON格式的基本概念、结构体的序列化与反序列化、结构体标签的使用以及如何实现链式编程。
39 4
|
2月前
|
JSON 数据格式
序列化 json和pickle
序列化 json和pickle
|
3月前
|
存储 JSON JavaScript
python序列化: json & pickle & shelve 模块
python序列化: json & pickle & shelve 模块
|
3月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
24天前
|
存储 安全 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第22天】在Java的世界里,对象序列化和反序列化是数据持久化和网络传输的关键技术。本文将带你了解如何在Java中实现对象的序列化与反序列化,并探讨其背后的原理。通过实际代码示例,我们将一步步展示如何将复杂数据结构转换为字节流,以及如何将这些字节流还原为Java对象。文章还将讨论在使用序列化时应注意的安全性问题,以确保你的应用程序既高效又安全。
|
1月前
|
存储 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第9天】在Java的世界里,对象序列化是连接数据持久化与网络通信的桥梁。本文将深入探讨Java对象序列化的机制、实践方法及反序列化过程,通过代码示例揭示其背后的原理。从基础概念到高级应用,我们将一步步揭开序列化技术的神秘面纱,让读者能够掌握这一强大工具,以应对数据存储和传输的挑战。