云备份day02

📟作者主页:慢热的陕西人

🌴专栏链接:C++云备份项目

📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言

主要内容介绍了第三方库jsoncpp和bundle库的使用

在这里插入图片描述

文章目录

  • 云备份day02
    • 1.Json库的使用
      • 1.1JSON与JSONCPP简介
      • 1.2安装JSONCPP
      • 1.3JSONCPP的基本使用
        • 1.3.1读取JSON数据
        • 1.3.2写入JSON数据
      • 1.4json的数据对象类
        • 1.4.1 Json::Value
        • 1.4.2 Json::Reader
        • 1.4.3Json::Writer
      • 1.5json序列化和反序列化的例子
    • 2.bundle文件压缩库的使用
      • 2.1尝试使用bundle库来实现文件的压缩
      • 2.2使用bundle库来实现文件的解压缩

云备份day02

1.Json库的使用

在现代软件开发中,数据的交换与处理是不可或缺的一环,尤其是在多平台、多语言的环境下。这里,我们要探讨的是JSONCPP —— 一个处理JSON数据的C++库,它提供了一套丰富的API来解析、构造、操作和序列化JSON数据。让我们从头开始,逐步深入了解JSONCPP的使用。

1.1JSON与JSONCPP简介

**JSON(JavaScript Object Notation)**是一种轻量级的数据交换格式。它基于文本,易于人类阅读和编写,同时也易于机器解析和生成。JSON主要用于存储和交换文本信息,格式简洁明了,具有良好的自描述性,因此被广泛应用于Web API、配置文件和数据库之间的数据交换。

JSONCPP是一个在C++中处理JSON数据的库,它提供了强大的功能,包括读取JSON数据、写入JSON数据、数据操作和查询等。通过JSONCPP,开发者可以在C++项目中轻松地实现复杂的JSON数据处理任务。

1.2安装JSONCPP

在开始使用JSONCPP之前,首先需要将其集成到你的C++项目中。JSONCPP可以通过多种方式安装,包括源码编译、包管理器(如vcpkg、apt-get)或直接在某些IDE中添加依赖。

# 例如,使用apt-get在Ubuntu中安装JSONCPP
sudo apt-get install libjsoncpp-dev

1.3JSONCPP的基本使用

在JSONCPP中,Json::Value是最核心的类,它代表了JSON数据中的任意元素,无论是一个对象、数组还是基本数据类型。接下来,我们将通过一些基本示例来了解如何使用JSONCPP进行JSON数据的读取和写入。

1.3.1读取JSON数据

假设我们有一个JSON字符串,我们想要解析它并访问其中的数据。

#include <json/json.h>
#include <iostream>int main() {std::string strJson = R"({"name": "John Doe","age": 30,"is_student": false,"skills": ["C++", "Python", "JavaScript"]})";Json::Value root;   Json::Reader reader;bool parsingSuccessful = reader.parse(strJson, root);if (!parsingSuccessful) {std::cout << "Failed to parse JSON" << std::endl;return 1;}std::string name = root["name"].asString();int age = root["age"].asInt();bool isStudent = root["is_student"].asBool();std::cout << "Name: " << name << ", Age: " << age << ", Is Student: " << isStudent << std::endl;const Json::Value skills = root["skills"];for (int index = 0; index < skills.size(); ++index) {std::cout << "Skill " << index + 1 << ": " << skills[index].asString() << std::endl;}return 0;
}
1.3.2写入JSON数据

创建和修改JSON数据同样简单。我们可以通过操作Json::Value对象来构建一个JSON结构。

#include <json/json.h>
#include <iostream>int main() {Json::Value root;root["name"] = "Jane Doe";root["age"] = 25;root["is_student"] = true;root["skills"].append("C++");root["skills"].append("Python");root["skills"].append("JavaScript");Json::StreamWriterBuilder builder;const std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());writer->write(root, &std::cout);std::cout << std::endl;return 0;
}

接下来我们将详细介绍:

1.4json的数据对象类

//Json数据对象类
class Json::Value{Value &operator=(const Value &other); //Value重载了[]和=,因此所有的赋值和获取数据都可以通过Value& operator[](const std::string& key);//简单的方式完成 val["姓名"] = "小明";Value& operator[](const char* key);Value removeMember(const char* key);//移除元素const Value& operator[](ArrayIndex index) const; //val["成绩"][0]Value& append(const Value& value);//添加数组元素val["成绩"].append(88);ArrayIndex size() const;//获取数组元素个数 val["成绩"].size();std::string asString() const;//转string string name = val["name"].asString();const char* asCString() const;//转char* char *name = val["name"].asCString();Int asInt() const;//转int int age = val["age"].asInt();float asFloat() const;//转floatbool asBool() const;//转 bool
};//json序列化类,低版本用这个更简单
class JSON_API Writer 
{virtual std::string write(const Value& root) = 0;
}
class JSON_API FastWriter : public Writer 
{virtual std::string write(const Value& root);
}
class JSON_API StyledWriter : public Writer 
{virtual std::string write(const Value& root);
}
//json序列化类,高版本推荐,如果用低版本的接口可能会有警告
class JSON_API StreamWriter 
{virtual int write(Value const& root, std::ostream* sout) = 0;
}
class JSON_API StreamWriterBuilder : public StreamWriter::Factory 
{virtual StreamWriter* newStreamWriter() const;
}
//json反序列化类,低版本用起来更简单
class JSON_API Reader 
{bool parse(const std::string& document, Value& root, bool collectComments = true);
}
//json反序列化类,高版本更推荐
class JSON_API CharReader 
{virtual bool parse(char const* beginDoc, char const* endDoc,Value* root, std::string* errs) = 0;
}
class JSON_API CharReaderBuilder : public CharReader::Factory 
{virtual CharReader* newCharReader() const;
}
1.4.1 Json::Value

Json::Value 是JsonCpp库中的核心类,用于表示JSON数据的所有可能类型:null、布尔值、整数、实数(浮点数)、字符串、数组和对象。

#include <json/json.h>
#include <string>
#include <iostream>int main() {// 创建一个Json::Value对象Json::Value data;// 通过不同方式设置值data["integer"] = 1;  // 整数data["float"] = 1.1;  // 浮点数data["string"] = "example";  // 字符串data["boolean"] = true;  // 布尔值data["array"] = Json::arrayValue;  // 数组data["array"].append(1);  // 向数组中添加元素data["array"].append("two");data["object"] = Json::objectValue;  // 对象data["object"]["key"] = "value";  // 向对象中添加键值对// 打印生成的JSON字符串std::cout << data.toStyledString() << std::endl;return 0;
}
1.4.2 Json::Reader

Json::Reader 类用于将JSON格式的字符串解析为 Json::Value 对象。这对于读取JSON数据非常有用。

#include <json/json.h>
#include <string>
#include <iostream>int main() {std::string str = "{\"age\": 25, \"name\": \"John\"}";Json::Value root;Json::Reader reader;bool parsingSuccessful = reader.parse(str, root);if (parsingSuccessful) {std::cout << "Name: " << root["name"].asString() << std::endl;std::cout << "Age: " << root["age"].asInt() << std::endl;} else {std::cerr << "Failed to parse JSON" << std::endl;}return 0;
}
1.4.3Json::Writer

Json::Writer 是一个抽象基类,定义了将 Json::Value 对象转换成JSON格式字符串的接口。Json::FastWriterJson::StyledWriterJson::StyledStreamWriter 是继承自 Json::Writer 的具体实现类,用于生成不同风格的JSON字符串。

由于JsonCpp的较新版本推荐使用 Json::Value 自带的 toStyledString 方法直接生成字符串,Json::Writer 及其派生类的使用变得不那么常见。不过,如果需要更复杂的定制化输出,这些类仍然很有用。

#include <json/json.h>
#include <string>
#include <iostream>int main() {Json::Value root;root["action"] = "run";root["data"]["value"] = 10;// 使用StyledWriter生成格式化的JSON字符串Json::StyledWriter writer;std::string output = writer.write(root);std::cout << output << std::endl;return 0;
}

以上代码提供了使用JsonCpp处理JSON数据的基本方法,包括创建和操作JSON对象、解析JSON字符串和生成JSON字符串。

1.5json序列化和反序列化的例子

#include<iostream> // 引入标准输入输出流库,用于控制台输入输出。
#include<sstream> // 引入字符串流库,用于在内存中读写字符串。
#include<memory> // 引入智能指针库,提供对智能指针如 unique_ptr 的支持。
#include<string> // 引入字符串库,支持string类型的操作。
#include<jsoncpp/json/json.h> // 引入JsonCpp库,用于处理JSON数据的序列化与反序列化。
#include<cstring> // 引入字符串处理库。using namespace std; // 使用标准命名空间,避免每次调用标准库时都需要前缀 std::。int main() // 主函数,程序的入口点。
{const char* name = "小明"; // 定义常量字符指针,指向姓名字符串。int age = 18; // 定义整数变量,表示年龄。int score[] = {79, 82, 93}; // 定义整型数组,存储三个成绩。Json::Value rootw; // 创建Json::Value对象,用作JSON的根节点。rootw["姓名"] = name; // 向JSON对象添加“姓名”字段。rootw["年龄"] = age; // 向JSON对象添加“年龄”字段。// 循环添加成绩到JSON的“成绩”数组中。rootw["成绩"].append(score[0]);rootw["成绩"].append(score[1]);rootw["成绩"].append(score[2]);// 序列化JSON对象。Json::StreamWriterBuilder swb; // 创建StreamWriterBuilder对象,用于构建StreamWriter。unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter()); // 使用StreamWriterBuilder创建StreamWriter的unique_ptr。stringstream ss; // 创建一个stringstream对象,用作序列化的输出缓冲区。sw->write(rootw, &ss); // 使用StreamWriter将JSON对象序列化到stringstream。cout << ss.str() << endl; // 将序列化的JSON字符串输出到控制台。// 定义一个JSON字符串。string str = R"({"姓名" : "小明","年龄" : 18,"成绩" : [79, 82, 93]})";Json::Value rootr; // 创建用于反序列化的Json::Value对象。Json::CharReaderBuilder crb; // 创建CharReaderBuilder对象。string err; // 定义字符串以存储可能的错误信息。unique_ptr<Json::CharReader> cr(crb.newCharReader()); // 使用CharReaderBuilder创建CharReader的unique_ptr。// 尝试解析JSON字符串。bool ret = cr->parse(str.c_str(), str.c_str() + str.size(), &rootr, &err);if(ret == false) // 检查解析是否成功,这里有个逻辑错误,应该使用==比较。{cout << err << endl; // 如果解析失败,输出错误信息。return -1; // 并结束程序。}// 如果解析成功,输出解析得到的数据。cout << "姓名:" << rootr["姓名"].asString() << endl;cout << "年龄:" << rootr["年龄"].asInt() << endl;int sz = rootr["成绩"].size(); // 获取成绩数组的大小。cout << "成绩:";for(int i = 0; i < sz; ++i) cout << rootr["成绩"][i] << " "; // 循环输出每一项成绩。puts(""); // 输出换行。return 0; // 程序正常结束。
}

在这里插入图片描述

2.bundle文件压缩库的使用

Bundle是一个嵌入式C++压缩库,支持多种压缩算法和档案格式。设计上追求高压缩比和快速解压速度,可配置,且兼容C++03及C++11的可选特性。该库支持多种流和档案格式,如.bun和.zip,包括DEFLATE、LZMA、ZPAQ、LZ4、ZSTD、BROTLI等23种压缩算法。项目采用Zlib许可证,是一种宽松的使用许可。更多详情可以参考其GitHub仓库。

2.1尝试使用bundle库来实现文件的压缩

注意我们先将bundle.cppbundle.h都移动到当前的目录下,然后在编译的时候要连接pthread库.

#include<iostream>
#include<string>
#include<fstream>#include"bundle.h"using namespace std;void Usage(char* argv[])
{cout << "Usage:" << argv[0] << " origin_file " << "Zip_file" << endl;
}int main(int argc, char* argv[])
{if(argc != 3) {Usage(argv);return -1;}string ifilename = argv[1];string ofilename = argv[2];ifstream ifs;ifs.open(ifilename, ios::binary);ifs.seekg(0, ios::end); size_t fsz = ifs.tellg();ifs.seekg(0, ios::beg);string body;body.resize(fsz);ifs.read(&body[0], fsz);string packed = bundle::pack(bundle::LZIP, body);ofstream ofs;ofs.open(ofilename, ios::binary);ofs.write(&packed[0], packed.size());ifs.close();ofs.close();return 0;
}

压缩后的效果:其中b.cpp被压缩为b.cpp.lz

[mi@lavm-5wklnbmaja Pre_study]$ ls -lh
total 15M
-rw-rw-r-- 1 mi mi 5.4M Apr  2 19:54 b.cpp
-rw-rw-r-- 1 mi mi 668K Apr  2 19:55 b.cpp.lz
-rw-rw-r-- 1 mi mi 5.4M Apr  2 19:51 bundle.cpp
-rw-rw-r-- 1 mi mi  29K Apr  2 19:32 bundle.h
-rwxrwxr-x 1 mi mi 3.2M Apr  2 19:53 compress
-rw-rw-r-- 1 mi mi  790 Apr  2 19:56 compress.cpp
-rw-rw-r-- 1 mi mi 3.0K Apr  2 19:06 JsonTest.cpp

2.2使用bundle库来实现文件的解压缩

#include<iostream>   // 包含输入输出库
#include<string>     // 包含字符串库
#include<fstream>    // 包含文件操作库
#include"bundle.h"  // 包含定义的bundle库
using namespace std;
// 用于在参数数量不正确时显示正确的使用方式
void Usage(char* argv[])
{// 输出正确的使用方式cout << \"Usage:\" << argv[0] << \" Zip_file \" << \"UnZip_file\" << endl;
}
int main(int argc, char* argv[])
{// 如果参数数量不正确,显示使用方法并返回错误码if(argc != 3) {Usage(argv);return -1;}// 获取压缩和解压文件的名字string ifilename = argv[1];string ofilename = argv[2];ifstream ifs;  // 创建一个ifstream 对象ifs.open(ifilename, ios::binary); // 以二进制方式打开压缩文件ifs.seekg(0, ios::end);  // 获取压缩文件的大小size_t fsize = ifs.tellg();ifs.seekg(0, ios::beg);  // 回到文件开头string body;body.resize(fsize);    // 将压缩文件的内容读入内存ifs.read(&body[0], fsize); // 读取文件内容ifs.close(); // 关闭压缩文件// 使用bundle库的unpack函数解压文件内容string unpacked = bundle::unpack(body);ofstream ofs;     // 创建一个ofstream 对象ofs.open(ofilename, ios::binary); //以二进制方式打开解压文件ofs.write(&unpacked[0], unpacked.size()); // 将解压后的内容写入解压文件// 关闭解压文件ofs.close();//主函数返回值return 0;
}

到这本篇博客的内容就到此结束了。
如果觉得本篇博客内容对你有所帮助的话,可以点赞,收藏,顺便关注一下!
如果文章内容有错误,欢迎在评论区指正

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/794313.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android 使用ollvm混淆so

使用到的工具 ndk 21.4.7075529&#xff08;android studio上下载的&#xff09;cmake 3.10.2.4988404&#xff08;android studio上下载的&#xff09;llvm-9.0.1llvm-mingw-20230130-msvcrt-x86_64.zipPython 3.11.5 环境配置 添加cmake mingw环境变量如下图: 编译 下载…

Codeforces Round 836 (Div. 2) D. Range = √Sum

题目 思路&#xff1a; #include <bits/stdc.h> using namespace std; #define int long long #define pb push_back #define fi first #define se second #define lson p << 1 #define rson p << 1 | 1 const int maxn 1e6 5, inf 1e18, maxm 4e4 5; c…

PyQt qrc2py 使用PowerShell将qrc文件转为py文件并且将导入模块PyQt或PySide转换为qtpy模块开箱即用

前言 由于需要使用不同的qt环境&#xff08;PySide&#xff0c;PyQt&#xff09;所以写了这个脚本&#xff0c;使用找到的随便一个rcc命令去转换qrc文件&#xff0c;然后将导入模块换成qtpy这个通用库(支持pyside2-6&#xff0c;pyqt5-6)&#xff0c;老版本的是Qt.py(支持pysi…

【力扣每日一题】1026. 节点与其祖先之间的最大差值

LC 1026. 节点与其祖先之间的最大差值 题目描述 给定二叉树的根节点 root&#xff0c;找出存在于 不同 节点 A 和 B 之间的最大值 V&#xff0c;其中 V |A.val - B.val|&#xff0c;且 A 是 B 的祖先。 &#xff08;如果 A 的任何子节点之一为 B&#xff0c;或者 A 的任何子…

算法刷题Day23 | 回溯算法基础理论、 77. 组合

目录 0 引言1 回溯算法基础理论1.1 回溯算法模板1.2 2 组合2.1 我的解题2.2 剪枝操作 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;算法专栏&#x1f4a5; 标题&#xff1a;算法刷题Day23 | 回溯算法基础理论、 77. 组合❣️ 寄语&#xff1a;书…

贪心算法|455.分发饼干

力扣题目链接 class Solution { public:int findContentChildren(vector<int>& g, vector<int>& s) {sort(g.begin(), g.end());sort(s.begin(), s.end());int index s.size() - 1; // 饼干数组的下标int result 0;for (int i g.size() - 1; i > 0;…

简约好用的TCPUDP小工具

csdn下载地址&#xff1a; https://download.csdn.net/download/a876106354/89077745

木棍【dfs搜索优化】

木棒 题目描述 输入样例&#xff1a; 9 5 2 1 5 2 1 5 2 1 4 1 2 3 4 0输出样例&#xff1a; 6 5【思路】 优化 【AC代码】 #include <iostream> #include <algorithm> #include <cstring>using namespace std;const int N 70;int w[N], sum, length,…

阿里云邮件服务器多少钱?邮件服务器租用费用

阿里云邮件服务器租用费用&#xff0c;2核2G3M带宽99元一年、2核4G4M服务器199元一年&#xff0c;不只是云服务器ECS&#xff0c;还可以选择轻量应用服务器。 0、在阿里云CLUB中心领取 aliyun.club 当前最新的优惠券和服务器报价单 1、阿里云服务器ECS经济型e实例&#xff0c;2…

专题三——二分算法

目录 原理 模板 朴素二分算法 非朴素二分算法 一二分查找 二在排序数组中查找元素的第一个和最后一个位置 三点名 四x的平方根 五搜索插入位置 六山脉数组的峰顶索引 七寻找峰值 八寻找旋转排序数组中的最小值 原理 定义两个指针&#xff1a;left指向数组第一个元…

Redis -- 缓存雪崩问题

缓存雪崩是指在同一时段大量的缓存key同时失效或者Redis服务宕机&#xff0c;导致大量请求到达数据库&#xff0c;带来巨大压力。 可能原因 : 同一时间大量的key到期 ; 解决方案&#xff1a; 给不同的Key的TTL添加随机值 利用Redis集群提高服务的可用性 给缓存业务添加降…

渗透测试靶机----Raven-1

渗透测试靶机----Raven-1 开启靶机&#xff0c;登录窗&#xff0c;平平无奇 开扫&#xff1a; 先看看ip 这里发现192.168.217.166 发现相关服务端口&#xff0c;这里看到80&#xff0c;还是老样子&#xff0c;先80入手打开发现一个熟悉的站点&#xff1a; 这里可以使用漏扫工具…

ES学习日记(五)-------插件head安装

接上回,必要的git和node已经装完了,现在开始装head 回到es集群项目里找到plugins(插件文件夹下), 存在安装在plugins启动es报错的情况,报错信息如图一,解决方案就是换个目录,不要放在plugin目录下 git clone https://github.com/mobz/elasticsearch-head.git 打开远程登陆,默…

【动手学深度学习】深入浅出深度学习之RMSProp算法的设计与实现

目录 &#x1f31e;一、实验目的 &#x1f31e;二、实验准备 &#x1f31e;三、实验内容 &#x1f33c;1. 认识RMSProp算法 &#x1f33c;2. 在optimizer_compare_naive.py中加入RMSProp &#x1f33c;3. 在optimizer_compare_mnist.py中加入RMSProp &#x1f33c;4. 问…

atoi()函数---使用和模拟实现(详解)

目录 一、前言二、声明三、描述四、参数五、返回值六、使用七、模拟实现 一、前言 二、声明 int atoi(const char *str)三、描述 C 库函数 int atoi(const char *str) 把参数 str 所指向的字符串转换为一个整数&#xff08;类型为 int 型&#xff09;需要包含头文件&#xff…

大语言模型基石:文字与数字的起源与演变

大语言模型基石&#xff1a;文字与数字的起源与演变 1、文字 1.1、起源 我们的祖先在还没有发明文字和语言之前就已经开始使用“咿咿呀呀”的声音来传播信息了&#xff0c;比如在野外活动遇到危险&#xff0c;然后发出“咿咿呀呀”的声音来提醒同伴小心&#xff0c;同伴在接收…

考古:IT架构演进之IOE架构

考古&#xff1a;IT架构演进之IOE架构 IOE架构&#xff08;IBM, Oracle, EMC&#xff09;出现在20世纪末至21世纪初&#xff0c;是一种典型的集中式架构体系。在这个阶段&#xff0c;企业的关键业务系统往往依赖于IBM的小型机&#xff08;后来还包括大型机&#xff09;、Oracle…

基于SpringBoot+Vue的儿童书法机构管理系统

一、项目背景介绍&#xff1a; 儿童书法机构的管理是一个具有挑战性的任务&#xff0c;需要有效的信息管理和资源分配。传统的手动管理方式存在着效率低下、易出错等问题。为了解决这些问题&#xff0c;基于SpringBootVue的儿童书法机构管理系统应运而生。该系统利用现代化的技…

Linux--进程(2)

目录 前言 1. 进程的状态 1.1 进程排队 1.2 运行&#xff0c;阻塞&#xff0c;挂起 2.Linux下具体的进程状态 2.1僵尸和孤儿 3.进程的优先级 4.Linux的调度与切换 前言 这篇继续来学习进程的其它知识 上篇文章&#xff1a;Linux--进程&#xff08;1&#xff09;-CS…

ES12 学习

文章目录 1. 逻辑赋值操作符2. 数字分隔符_3. replaceAll4. Promise.any5. WeakRefs6. FinalizationRegistry 1. 逻辑赋值操作符 逻辑赋值操作符 ??、&&、|| let a true let b true a && b // a a && b a || b // a a || b obj.introduction ?…