文章目錄
- 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;
}