云备份项目(代码片段)

qnbk qnbk     2022-12-04     739

关键词:

云备份

云备份:自动将本地计算机上指定文件夹中需要备份的文件上传备份到服务器中。并且能够随时通过浏览器进行查看并且下载,其中下载过程支持断点续传功能,而服务器也会对上传文件进行热点管理,将非热点文件进行压缩存储,节省磁盘空间。

目标:们实现两端程序,其中包括部署在用户机的客户端程序,上传需要备份的文件,以及运行在服务器上的服务端程序,实现备份文件的存储和管理,两端合作实现总体的自动云备份功能。

服务端程序

负责功能

  • 客户端上传的文件进行备份存储
  • 能够对文件进行热点文件管理,对非热点文件进行压缩存储,节省磁盘空间
  • 支持客户端浏览器查看访问文件列表。
  • 支持客户端浏览器下载文件,并且下载支持断点续传。

模块划分

  • 数据管理模块:负责服务器上备份文件的信息管理。
  • 网络通信模块:搭建网络通信服务器,实现与客户端通信。
  • 业务处理模块:针对客户端的各个请求进行对应业务处理并响应结果。
  • 热点管理模块:负责文件的热点判断,以及非热点文件的压缩存储。

客户端程序

负责功能

  • 能够自动检测客户机指定文件夹中的文件,并判断是否需要备份
  • 将需要备份的文件逐个上传到服务器

模块划分

  • 数据管理模块:负责客户端备份的文件信息管理,通过这些数据可以确定一个文件是否需要备份。
  • 文件检测模块:遍历获取指定文件夹中所有文件路径名称。
  • 网络通信模块:搭建网络通信客户端,实现将文件数据备份上传到服务器。

环境搭建

gcc7.3版本

sudo yum install centos-release-scl-rh centos-release-scl
sudo yum install devtoolset-7-gcc devtoolset-7-gcc-c++
source /opt/rh/devtoolset-7/enable 
echo "source /opt/rh/devtoolset-7/enable" >> ~/.bashrc

安装jsoncpp库

sudo yum install epel-release
sudo yum install jsoncpp-devel
ls /usr/include/jsoncpp/json/

下载bundle数据压缩库

sudo yum install git
git clone https://github.com/r-lyeh-archived/bundle.git

下载 httplib 库

git clone https://github.com/yhirose/cpp-httplib.git

json

json 是一种数据交换格式,采用完全独立于编程语言的文本格式来存储和表示数据。
举例:

char name = "jack";
int age = 18;
float score[3] = 88.5, 99, 58;
//json这种数据交换格式是将这多种数据对象组织成为一个字符串:
[
   
        "name" : "jack",
        "age" : 18,
        "score" : [88.5, 99, 58]
   ,
   
        "name" : "rose",
        "age" : 20,
        "score" : [88.5, 99, 58]
   
]

json 数据类型:对象,数组,字符串,数字
对象:使用花括号 括起来的表示一个对象。
数组:使用中括号 [] 括起来的表示一个数组。
字符串:使用常规双引号 “” 括起来的表示一个字符串
数字:包括整形和浮点型,直接使用。

jsoncpp

jsoncpp 库用于实现 json 格式的序列化和反序列化,完成将多个数据对象组织成为 json 格式字符串,以及将 json格式字符串解析得到多个数据对象的功能。
这其中主要借助三个类以及其对应的少量成员函数完成:

//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;

jsoncpp 实现序列化

#include <iostream>
#include <sstream>
#include <string>
#include <memory>
#include <jsoncpp/json/json.h>

int main()

  const char *name = "jack";
  int age = 18;
  float score[] = 70,80,90;
  Json::Value root;
  root["name"] =name;
  root["age"] = age;
  root["score"].append(score[0]);
  root["score"].append(score[1]);
  root["score"].append(score[2]);
  Json::StreamWriterBuilder swb;
  std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
  std::stringstream ss;
  sw->write(root,&ss);
  std::cout << ss.str() << std::endl;
  return 0;


g++ json_example.cpp  -o json_example -ljsoncpp

jsoncpp 实现反序列化

#include <iostream>
#include <string>
#include <memory>
#include <jsoncpp/json/json.h>

int main()


  std::string str = R"("name":"lily","age":20,"score":[10,30,20])";
  Json::Value root;
  Json::CharReaderBuilder crb;
  std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
  std::string err;
  bool ret = cr->parse(str.c_str(),str.c_str()+str.size(),&root,&err);
  if(ret == false)
    std::cout<<"parse error"<<std::endl;
    return -1;
  
  std::cout<<root["name"].asString()<<std::endl;
  std::cout<<root["age"].asString()<<std::endl;
  int sz = root["score"].size();
  for(int i = 0;i < sz;i++)
    std::cout<<root["score"][i]<<std::endl;
  
  return 0;


bundle文件压缩库

BundleBundle 是一个嵌入式压缩库,支持23种压缩算法和2种存档格式。使用的时候只需要加入两个文件bundle.h 和 bundle.cpp 即可。

namespace bundle

  // low level API (raw pointers)
  bool is_packed( *ptr, len );
  bool is_unpacked( *ptr, len );
  unsigned type_of( *ptr, len );
  size_t len( *ptr, len );
  size_t zlen( *ptr, len );
  const void *zptr( *ptr, len );
  bool pack( unsigned Q, *in, len, *out, &zlen );
  bool unpack( unsigned Q, *in, len, *out, &zlen );
  // medium level API, templates (in-place)
  bool is_packed( T );
  bool is_unpacked( T );
  unsigned type_of( T );
  size_t len( T );
  size_t zlen( T );
  const void *zptr( T );
   bool unpack( T &, T );
  bool pack( unsigned Q, T &, T );
  // high level API, templates (copy)
  T pack( unsigned Q, T );
  T unpack( T );

bundle库实现文件压缩

cp bundle/bundle.cpp bundle/bundle.h Linux/cloude/

把bundle.cpp,bundle.h拷贝到当前操作的文件夹中

#include <iostream>
#include <string>
#include <fstream>
#include "bundle.h"
int main(int argc,char* argv[])

  std::cout<<"argv[1]是原始路径名称"<<std::endl;
  std::cout<<"argv[2]是压缩包名称"<<std::endl;
  if(argc < 3)
    return -1;
  std::string ifilename = argv[1];
  std::string ofilename = argv[2];
  std::ifstream ifs;
  ifs.open(ifilename,std::ios::binary);//打开原始文件
  ifs.seekg(0,std::ios::end);//跳转读写位置到末尾
  size_t fsize = ifs.tellg();//获取末尾偏移量--文件长度
  ifs.seekg(0,std::ios::beg);//跳转到文件起始
  std::string body;
  body.resize(fsize);//调整body大小为文件大小
  ifs.read(&body[0],fsize);//读取文件所有数据到body

  std::string packed = bundle::pack(bundle::LZIP,body);//以lzip格式压缩文件数据
  std::ofstream ofs;
  ofs.open(ofilename,std::ios::binary);//打开压缩包文件
  ofs.write(&packed[0],packed.size());//将压缩后的数据写入压缩包文件
  ifs.close();
  ofs.close();
  return 0;


g++ compress.cpp bundle.cpp -o compress -lpthread

bundle库实现文件解压缩

#include <iostream>
#include <fstream>
#include <string>
#include "bundle.h"

int main(int argc,char* argv[])

  if(argc < 3)
    std::cout<<"argv[1]是压缩åŒ
名称"<<std::endl;
    std::cout<<"argv[2]是解压后的文件名称"<<std::endl;
    return -1;
  
  std::string ifilename = argv[1];//压缩åŒ
名
  std::string ofilename = argv[2];//解压后的文件名
  std::ifstream ifs;
  ifs.open(ifilename,std::ios::binary);
  ifs.seekg(0,std::ios::end);
  size_t fsize = ifs.tellg();
  ifs.seekg(0,std::ios::beg);
  std::string body;
  body.resize(fsize);
  ifs.read(&body[0],fsize);
  ifs.close();

  std::string unpacked = bundle::unpack(body);
  std::ofstream ofs;
  ofs.open(ofilename,std::ios::binary);
  ofs.write(&unpacked[0],unpacked.size());
  ofs.close();
  return 0;


g++ uncompress.cpp bundle.cpp  -o uncompress -lpthread

httplib 库

httplib 库,一个 C++11 单文件头的跨平台 HTTP/HTTPS 库。安装起来非常容易。只需包含 httplib.h 在你的代码中即可。 httplib 库实际上是用于搭建一个简单的 http

服务器或者客户端的库,这种第三方网络库,可以让我们免去搭建服务器或客户端的时间,把更多的精力投入到具体的业务处理中,提高开发效率

namespace httplib
    struct MultipartFormData 
        std::string name;
          std::string content;
        std::string filename;
        std::string content_type;
   ;
    using MultipartFormDataItems = std::vector<MultipartFormData>;
    struct Request 
        std::string method;
        std::string path;
        Headers headers;
        std::string body;
        // for server
        std::string version;
        Params params;
        MultipartFormDataMap files;
        Ranges ranges;
        bool has_header(const char *key) const;
        std::string get_header_value(const char *key, size_t id = 0) const;
        void set_header(const char *key, const char *val);
        bool has_file(const char *key) const;
        MultipartFormData get_file_value(const char *key) const;
   ;
    struct Response 
        std::string version;
        int status = -1;
        std::string reason;
        Headers headers;
        std::string body;
        std::string location; // Redirect location
 void set_header(const char *key, const char *val);
        void set_content(const std::string &s, const char *content_type);
   ;
 class Server 
        using Handler = std::function<void(const Request &, Response &)>;//函数指针类型
        using Handlers = std::vector<std::pair<std::regex, Handler>>;//请求与处理函数映射表
        std::function<TaskQueue *(void)> new_task_queue;//线程池-用于处理请求
        Server &Get(const std::string &pattern, Handler handler);
 Server &Post(const std::string &pattern, Handler handler);
        Server &Put(const std::string &pattern, Handler handler);
 Server &Patch(const std::string &pattern, Handler handler);  
 Server &Delete(const std::string &pattern, Handler handler);
 Server &Options(const std::string &pattern, Handler handler);
        bool listen(const char *host, int port, int socket_flags = 0);
 ;
    class Client 
        Client(const std::string &host, int port);
 Result Get(const char *path, const Headers &headers);
        Result Post(const char *path, const char *body, size_t content_length,
              const char *content_type);
        Result Post(const char *path, const MultipartFormDataItems &items);
   

  • handler:函数指针类型,定义了一个http请求处理回调函数格式。httplib搭建的服务器收到请求后,进行解析,得到一个Request结构体其中包含了请求数据,根据请求数据就可以处理请求,这个处理函数定义的格式就是Handler格式
  • Request参数:保存请求数据,让用户根据请求数据进行业务处理
  • Response参数:需要用户在业务处理中,填充数据,最终要响应给客户端
  • regex:正则表达式-用于匹配http请求资源
  • httplib收到一个新建链接,则将新的客户端连接到线程池中

handlers可以理解为一张表,映射了一个客户端请求的资源路径和一个处理函数(用户自己定义的函数),当服务器收到请求解析得到Request就会根号资源路径以及请求方法到这张表中查看有没有对应的函数,如果有则调用这个函数处理请求,如果没有,则响应404

线程池中的线程工作:1、收到请求,解析请求,得到Request结构体也就是请求的数据2、在handlers映射表中根据请求信息查找处理函数

httplib 库搭建简单服务器

#include "httplib.h"

void hello(const httplib::Request &req,httplib::云备份项目(代码片段)

云备份项目文章目录云备份项目云备份的认识项目实现目标模块划分第三方库认识JSON认识bundle文件压缩库httplib库httplib库搭建服务器httplib库搭建客户端项目实现云备份服务端实现数据管理模块文件操作工具类Json操作工具类文件... 查看详情

使用云祺虚拟机备份软件备份citrixxenserver虚拟机(代码片段)

1、进入云祺虚拟机备份系统,选择【备份/恢复】——【虚拟机备份】,新建备份任务。2、在CitrixXenServer虚拟化类型下勾选要备份的虚拟机,选择的虚拟机即显示在【已选择的虚拟机】下面,滚动页面到底部,点击【下一步】。... 查看详情

备份数据上传腾讯云cos(代码片段)

一、方案背景由于服务器上数据量越来越大,备份的数据会占用硬盘空间(虽说云硬盘可随时扩容,但是存在风险),定时将备份上传到COS。不仅节省服务器硬盘空间,也大大提高备份数据的安全性、可靠性。二、操作步骤1、软件... 查看详情

使用云祺虚拟机备份软件备份h3ccas虚拟机(代码片段)

1、进入云祺虚拟机备份系统,选择【备份/恢复】——【虚拟机备份】,新建备份任务。2、在H3CCAS虚拟化类型下勾选要备份的虚拟机,选择的虚拟机即显示在【已选择的虚拟机】下面,滚动页面到底部,点击【下一步】。3、备... 查看详情

备份本地库到远端ucloud云存储(代码片段)

备份本地mysql数据到Ucloud存储,支持STANDARD,IA,ARCHIVE标准存储,低频存储(IA)或者冷存储(ARCHIVE)这3中存储类型#注意如果,欲使用低频存储(IA)或者冷存储(ARCHIVE),请在命令参数storageclass中指定,支持三种值:STANDARD,IA,ARCHIVE#注意如果... 查看详情

openstack云主机跨项目迁移(代码片段)

...台修改网络类型为共享网络openstacknetworksetxxxxxxx--share2、备份数据库dockerexec-it-urootmariadbmysqldump-uroot-pxxxxxxxxxxxnovainstances>nova_instances.sqldockerexec-it-urootmariadbmysqldump-uroot-pxxxxxxxxxxxnovainstance_info_caches>nova_instance_info_caches.sqldockerexec-i... 查看详情

使用云祺虚拟机备份软件备份sanforhci虚拟机(代码片段)

1、进入云祺虚拟机备份系统,选择【备份/恢复】——【虚拟机备份】,新建备份任务。2、在SANFORHCI虚拟化类型下勾选要备份的虚拟机,选择的虚拟机即显示在【已选择的虚拟机】下面,滚动页面到底部,点击【下一步】。3、... 查看详情

项目云备份项目简介

项目简介:搭建云备份服务器客户端,实现客户端针对指定目录文件自动备份到云端,服务器端会对上传的文件热点判断,非热点压缩存储到磁盘。通过浏览器可以查看与下载(支持断点续传)。概要设计... 查看详情

项目云备份项目简介

项目简介:搭建云备份服务器客户端,实现客户端针对指定目录文件自动备份到云端,服务器端会对上传的文件热点判断,非热点压缩存储到磁盘。通过浏览器可以查看与下载(支持断点续传)。概要设计... 查看详情

项目云备份项目简介

项目简介:搭建云备份服务器客户端,实现客户端针对指定目录文件自动备份到云端,服务器端会对上传的文件热点判断,非热点压缩存储到磁盘。通过浏览器可以查看与下载(支持断点续传)。概要设计... 查看详情

mysql自动备份并提交到码云git仓库–任我乐(代码片段)

...对于个人开发者似乎也是一笔不小的费用。在创建自动将备份上传到码云仓库前,建议您先看下以下文章:《如何通过Git将本地项目推送到码云或GitHub》对于不太了解的朋友来说,此文章非常有用,否则在进行以下步骤时会出现... 查看详情

mysql自动备份并提交到码云git仓库–任我乐(代码片段)

...对于个人开发者似乎也是一笔不小的费用。在创建自动将备份上传到码云仓库前,建议您先看下以下文章:《如何通过Git将本地项目推送到码云或GitHub》对于不太了解的朋友来说,此文章非常有用,否则在进行以下步骤时会出现... 查看详情

公司实现全网备份项目:(rsync+定时任务)(代码片段)

...,现在领导要求你把数据在其他机器上做一个周期性定时备份。要求如下:每天晚上12点整在Web服务器A(web01)上打包备份网站程序目录并通过rsync命令推送到服务器B(backup)上备份保留(备份思路可以是先在本地按日期打包,然后再... 查看详情

使用宝塔面板如何自动备份数据库和网站代码(代码片段)

...章来自于某框架的知名苦工仙士可的提问,你是怎么定时备份数据库的?基础操作是:宝塔自带的定时任务当中就有备份数据库和网站代码啊  然后就直接选择了备份到服务器磁盘把备份文件放在服务器上也是不太保险,... 查看详情

mysql5.7.40备份到腾讯云cos+从cos恢复(代码片段)

1备份1.1安装coscli#wgethttps://github.com/tencentyun/coscli/releases/download/v0.12.0-beta/coscli-linux#mvcoscli-linux/usr/bin/coscli#chmod755/usr/bin/coscli#coscli--version如果github慢可以使用国内镜像:wgetht 查看详情

客快物流大数据项目:docker的迁移与备份(代码片段)

Docker的迁移与备份一、容器保存为镜像可以通过以下命令将容器保存为镜像dockercommitmynginxmynginx_image基于新创建的镜像创建容器dockerrun-di--name=mynginx2-p81:80mynginx_image访问81端口二、镜像备份可以通过以下命令将镜像保存为tar文... 查看详情

python项目所需依赖库的备份与还原(代码片段)

在项目根目录下执行下面命令pipfreeze>requirements.txt用于生成当前项目所依赖的所有依赖库清单pipdownload-rrequirements.txt-dpackages/下载所需依赖包到当前路径下的packages/目录下pipinstall--no-index--find-links=packages/-rrequirements.txt离线还... 查看详情

项目实践云备份概述

项目简介:搭载云备份服务器和客户端,实现客户端对主机上特定目录下的文件自动进行备份到云端服务器端对上传文件进行热点文件判断,对于非热点文件进行压缩存储节省磁盘空间支持通过浏览器进行查看和下载... 查看详情