云备份day02

news2025/1/17 1:44:40

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

🌴专栏链接: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;//转float
	bool 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.coloradmin.cn/o/1572442.html

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

相关文章

关于Linux下的进程状态(进程篇)

目录 Linux操作系统的一般进程状态 关于阻塞 关于挂起 Linux内核状态源代码&#xff1a; 关于僵尸进程 关于孤儿进程 Linux操作系统的一般进程状态 新建&#xff1a;字面意思运行&#xff1a;task_struct结构体在运行队列中排队&#xff0c;就叫做运行态阻塞&#xff1a;等待非…

Java项目:基于Springboot+vue社区医院管理系统设计与实现(源码+数据库+毕业论文)

一、项目简介 本项目是一套基于Springbootvue社区医院管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、功能…

机器学习知识点全面总结

机器学习按照模型类型分为监督学习模型、无监督学习模型两大类。 1、有监督学习 有监督学习通常是利用带有专家标注的标签的训练数据&#xff0c;学习一个从输入变量X到输入变量Y的函数映射。Y f (X)&#xff0c;训练数据通常是(nx,y)的形式&#xff0c;其中n代表训练样本的大…

基于springboot实现甘肃非物质文化网站系统项目【项目源码+论文说明】

摘要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本甘肃非物质文化网站就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信…

Java Number类(详细)

一&#xff0c;Number java.lang.Number 类是抽象类&#xff0c;用于表示各种数值类型的对象。它是 Java 中所有数值类型的包装类的超类。Number 类主要有以下几个特点和作用&#xff1a; 抽象类&#xff1a;Number 类是一个抽象类&#xff0c;不能直接实例化&#xff0c;但可以…

计算机中数的表示

0. 简介 介绍计算机中数的表示方法&#xff0c;主要内容来自 c s a p p csapp csapp。 1. 整数的表示 包括有符号整数与无符号整数的表示。 假设 w → [ w n − 1 w n − 2 . . . w 0 ] \overrightarrow w[w_{n-1}w_{n-2}...w_0] w [wn−1​wn−2​...w0​] 为一种整数。…

【Python系列】将生成的 JSON 数据写入 JSON 文件

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

嵌入式开发学习---(部分)数据结构(无代码)

数据结构 为什么学习数据结构&#xff1f; 1&#xff09;c语言告诉如何写程序&#xff0c;数据结构是如何简洁高效的写程序 2&#xff09;遇到一个实际问题&#xff0c;需要写程序去实现相应功能&#xff0c;需要解决那两个方面的问题&#xff1f; 如何表达数据之间的逻辑规律…

智慧公厕,城市管理新亮点

在现代城市环境建设中&#xff0c;智慧公厕作为智慧环卫的重要组成部分&#xff0c;正以其先进的技术手段&#xff0c;成为城市管理的亮点和标杆。借助物联网等技术的应用&#xff0c;智慧公厕实现了信息化、数字化、智慧化的全面升级&#xff0c;为市民提供了更便捷舒适的公共…

[WIP]Sora相关工作汇总VQGAN、MAGVIT、VideoPoet

视觉任务相对语言任务种类较多(detection, grounding, etc.)、粒度不同 (object-level, patch-level, pixel-level, etc.)&#xff0c;且部分任务差异较大&#xff0c;利用Tokenizer核心则为如何把其他模态映射到language space&#xff0c;并能让语言模型更好理解不同的视觉任…

Linux安装及管理程序(rpm)

目录 一.Linux应用程序基础 1.应用程序与系统命令的关系 2.典型应用程序的目录结构 3.常见的软件包封装类型 二.RPM包管理工具 1.rmp 查询 2.rpm安装与卸载 3.维护 RPM 数据库 一.Linux应用程序基础 1.应用程序与系统命令的关系 对比系统命令和应用程序的不同 1.1位…

聚簇索引与非聚簇索引b+树实现的区别

文章目录 聚簇索引非聚簇索引B树中聚簇索引的查找&#xff08;匹配&#xff09;逻辑B树中非聚簇索引的查找&#xff08;匹配&#xff09;逻辑 聚簇索引 特点&#xff1a; 索引和数据保存在同一个B树中 页内的记录是按照主键的大小顺序排成一个单向链表 。 页和页之间也是根据…

Vite 项目中环境变量的配置和使用

Vite 项目中环境变量的声明 我们要在 Vite 项目中进行环境变量的声明&#xff0c;那么需要在项目的根目录下&#xff0c;新建 .env.[mode] 文件用于声明环境变量&#xff0c;如&#xff1a; .env.test 文件用于测试环境下项目全局变量的声明.env.dev 文件用于开发环境下项目全…

FastWiki发布`0.2.4`支持js 函数

Release v0.2.4 AIDotNet/fast-wiki (github.com) 支持JS动态functioncall调用支持动态function管理支持JS在线编辑提供智能代码提示支持JS在线编辑提供部分绑定的c#类&#xff08;默认提供Console&#xff0c;HttpClient&#xff09;支持Application绑定多个Function Call优…

异常处理之Java异常体系

Throwable java.lang.Throwable 类是Java程序执行过程中发生的异常事件对应的类的根父类。 Throwable中的常用方法&#xff1a; public void printStackTrace()&#xff1a;打印异常的详细信息。 包含了异常的类型、异常的原因、异常出现的位置、在开发和调试阶段都得使用prin…

NLP 在搜索引擎优化上做的工作

自然语言处理&#xff08;NLP&#xff09;在搜索引擎优化上的工作主要集中在提升搜索结果的相关性和准确性&#xff0c;以及改善用户的搜索体验。以下是NLP在搜索引擎优化中所做工作的详细介绍&#xff1a; 1. 理解用户查询意图【4】 NLP技术可以帮助搜索引擎更好地理解用户的…

LeetCode:1026. 节点与其祖先之间的最大差值(DFS Java)

目录 1026. 节点与其祖先之间的最大差值 题目描述&#xff1a; 实现代码与解析&#xff1a; DFS 原理思路&#xff1a; 1026. 节点与其祖先之间的最大差值 题目描述&#xff1a; 给定二叉树的根节点 root&#xff0c;找出存在于 不同 节点 A 和 B 之间的最大值 V&#xff…

如何不花一分冤枉钱开视频号小店?按照我的方法,让你省下好几千

大家好&#xff0c;我是电商糖果 因为去年不少人靠做视频号小店发了大财&#xff0c;今年不少创业者&#xff0c;盯上了这个新出来的“电商平台”了。 就是因为它是新出来的平台&#xff0c;平台为了维护项目的红利&#xff0c;以及大量无良商家的入驻&#xff0c;入驻门槛会…

Canal1.1.5整Springboot在MQ模式和TCP模式监听mysql

canal本实验使用的是1.1.5&#xff0c;自行决定版本&#xff1a;[https://github.com/alibaba/canal/releases] canal 涉及的几个角色 canal-admin&#xff1a;canal 后台管理系统&#xff0c;管理 canal 服务canal-deployer&#xff1a;即canal-server&#xff08;客户端&…

Git 术语及中英文对照

完毕&#xff01;&#xff01;感谢您的收看 ----------★★历史博文集合★★---------- 我的零基础Python教程&#xff0c;Python入门篇 进阶篇 视频教程 Py安装py项目 Python模块 Python爬虫 Json Xpath 正则表达式 Selenium Etree CssGui程序开发 Tkinter Pyqt5 列表元组字…