文章目录
- 1. JSON是什么
- 2. JSON的特点与结构
- 3. JSON的使用
- 4. JSON文件读取
1. JSON是什么
JSON(JavaScript Object Notation,JavaScript对象表示法)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。JSON起源于JavaScript语言,但已成为一种独立于编程语言的数据格式。它由键值对组成,类似于JavaScript中的对象,但更加简洁和通用化。JSON数据以文本形式存储,易于解析和生成,因此被广泛应用于数据交换和存储。
2. JSON的特点与结构
JSON的特点
- 文本格式:JSON是一种纯文本格式,可以存储和传输数据。
- 语言无关性:虽然基于JavaScript,但JSON可以被多种编程语言解析。
- 数据交换:常用于Web应用之间的数据交换。
- 易于阅读和编写:格式简洁,易于理解和使用。
- 自我描述:结构清晰,不需要额外的解释文档。
JSON的基本结构
JSON数据格式支持以下几种数据结构:
- 对象:由花括号{}包围,包含一系列键值对。
- 数组:由方括号[]包围,包含一系列值。
- 字符串:必须用双引号"包围。
- 数字:整数或浮点数。
- 布尔值:true或false。
- null:表示空值。
3. JSON的使用
为什么要用json文件应用比较多呢?
我们最常使用的存储数据的方式有很多,比如利用txt文件存,利用xml存,利用word存,利用Excel存,如果我们要求比较高,还可以使用数据库存。
- 相对于txt,word来说,json格式更加明确,获取重要信息非常方便。
- 相对于xml来说,json格式更加简洁,存储同样的文件,花费的内存更小。
- 相对于Excel来说,json更适合存储字符类文件。Excel相当于比较简单的数据库了。
- 相对于数据库来说,json更加方便,数据库我们还需要做一些设置,安装一些软件。json可以直接使用。
在数据传输使用时一般创建好JSON数据之后序列化为字符串再传输,接收方收到数据后再反序列化为字符串获取数据
在存储数据时的使用类似于简化版的键值对
这里展示cpp的使用
演示如下:
// json序列化示例代码
#include "json.hpp"
using json = nlohmann::json;#include <iostream>
#include <vector>
#include <map>
#include <string>
using namespace std;string func()
{json js;// 直接序列化一个vector容器vector<int> vec;vec.push_back(1);vec.push_back(2);vec.push_back(5);js["list"] = vec;// 直接序列化一个map容器map<int, string> m;m.insert({1, "挺好的?"});m.insert({2, "华山"});m.insert({3, "泰山"});js["path"] = m;string sendBuf = js.dump(); // json数据对象 =》序列化 json字符串//cout<<sendBuf<<endl;return sendBuf;
}int main()
{string recvBuf_1=func();json jsbuf_1=json::parse(recvBuf_1);//反序列化cout<<jsbuf_1["path"]<<endl;map<int,string> mymap=jsbuf_1["path"];for(auto t:mymap){cout<<t.second;}vector my_vector = jsbuf_1["list"];for(auto item:my_vector){cout<<item;}return 0;
}
4. JSON文件读取
定义的JSON数据结构如下
"Group Name" : "Togehter",
"Number" : 2,
"Students" : {"Lisi" : [165,50],"Zhangsan" : [180,70]
}
写文件如下:
#include <iostream>
#include <fstream>
#include "json.hpp"using namespace std;int main() {//根节点Json::Value root;root["Group Name"] = "Togehter";root["Number"] = 2;//Map形式root["Students"]["Zhangsan"].append(180);root["Students"]["Zhangsan"].append(70);root["Students"]["Lisi"].append(165);root["Students"]["Lisi"].append(50);//父子节点形式Json::Value student;student["Zhangsan"].append(180);student["Zhangsan"].append(70);student["Lisi"].append(165);student["Lisi"].append(50);root["Students"] = student;//格式化输出到文件 ofstream os; //实例化输出类os.open("test.json", std::ios::out); //打开并指定文件以输出方式打开(往文件里写)if (!os.is_open()) //检查文件打开情况cout << "open file failed" << endl;Json::StyledWriter sw; //定义格式化输出os << sw.write(root); //输出到文件 os.close(); //关闭文件return 0;
}
针对含有二级对象的内容,可以使用以下两种方式:
(1)map形式,这种方式较为简单,但缺点就是只能处理相对比较简单的二级对象。
在一级对象后直接跟不同的二级对象作为区分,并针对二级对象进行赋值或添加的操作。
root["Students"]["Zhangsan"].append(180); //添加身高信息
root["Students"]["Zhangsan"].append(70); //添加体重信息root["Students"]["Lisi"].append(165); //添加身高信息
root["Students"]["Lisi"].append(50); //添加体重信息
(2)父子节点的形式,这种方法可以定义更为复杂的形式,缺点就是定义起来较为麻烦。
定义子节点,然后按照与根节点相同的方式对子节点进行处理,最后将其链接到根节点即可。
Json::Value student; //定义子节点
student["Zhangsan"].append(180);
student["Zhangsan"].append(70);student["Lisi"].append(165);
student["Lisi"].append(50);root["Students"] = student; //将子节点链接到根节点上
读取文件较为简单,如下:
#include <iostream>
#include <fstream>
#include "json.hpp"using namespace std;int main() {Json::Reader reader;Json::Value root;ifstream is("test.json", ios::binary); //打开文件,以二进制方式打开文件if (!is.is_open()) //检查文件打开情况cout << "open file failed" << endl;if (reader.parse(is, root)) {//读取根节点信息string group_name = root["Group Name"].asString();int number = root["Number"].asInt();cout << "Group Name: " << group_name << endl;cout << "Number: " << number << endl;//读取子节点信息int body[2]; //身高、体重/********注意遍历json数组的时候要使用unsigned int的变量********/body[0] = root["Students"]["Zhangsan"][(unsigned int)0].asInt(); body[1] = root["Students"]["Zhangsan"][(unsigned int)1].asInt();cout << "Zhangsan height:" << body[0] << " weight: " << body[1] << endl;body[0] = root["Students"]["Lisi"][(unsigned int)0].asInt();body[1] = root["Students"]["Lisi"][(unsigned int)1].asInt();cout << "Lisi height:" << body[0] << " weight: " << body[1] << endl;}is.close();return 0;
}