C++实现云备份项目

项目实现目标

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

项目设计

这个云备份项目需要我们实现两端程序,其中包括部署在用户机的客户端程序,上传需要备份的文
件,以及运行在服务器上的服务端程序,实现备份文件的存储和管理,两端合作实现总体的自动云
备份功能。
服务端负责功能
针对客户端上传的文件进行备份存储。
能够对文件进行热点文件管理,对非热点文件进行压缩存储,节省磁盘空间。
支持客户端浏览器查看访问文件列表。
支持客户端浏览器下载文件,并且下载支持断点续传。
客户端负责功能

能够自动检测客户机指定文件夹中的文件,并判断是否需要备份。

将需要备份的文件逐个上传到服务器。

项目环境

服务器: centos7(以上)/ vim、g++(7.3以上)、gdb、makefile

客户端: Windows10/ vs2017(以上)

使用到的库

Jsoncpp 库: 

jsoncpp 库用于实现 json 格式的序列化和反序列化,完成将多个数据对象组织成为 json 格式字符串,以及将 json 格式字符串解析得到多个数据对象的功能。

Bundle 库:
数据压缩及解压缩库, 在本项目中服务端的热点管理模块, 若判断文件不是热点文件使用bundle库将其压缩用户下载时再将其解压缩。
Httplib 库:
httplib 库实际上是用于搭建一个简单的 http 服务器或者客户端的库,这种第三方网络库,可以让我们免去搭建服务器或客户端的时间,把更多的精力投入到具体的业务处理中,提高开发效率。
C++17 filesystem库:

使用该库实现服务端和客户端的文件操作工具类实现( util.hpp ), 实现文件目录的创建, 检索文件是否存在, 获取不带路径的纯文件名, 浏览遍历指定目录下文件, 删除文件等操作。

模块实现

服务端数据管理模块
内存中以文件访问 URL key ,数据信息结构为 val ,使用哈希表进行管理,查询速度快。使用 url 作为 key 是因为往后客户端浏览器下载文件的时候总是以 url 作为请求。
采用文件形式对数据进行持久化存储(序列化方式采用 json 格式或者自定义方式)
要管理的数据: 原文件名,原文件大小,原文件时间属性,对应的压缩包名称,压缩标志
上传的文件,最终是用户在浏览器上进行查看并下载的,而浏览器界面上需要能够展示客户端曾经备份过的文件: 原文件名,文件大小,文件备份时间
服务端热点管理模块:
服务器端的热点文件管理是对上传的非热点文件进行压缩存储,节省磁盘空间
而热点文件的判断在于上传的文件的最后一次访问时间是否在热点判断时间之内,比如如果一个文件一天都没有被访问过我们就认为这是一个非热点文件,其实就是当前系统时间,与文件最后一次访问时间之间的时间差是否在一天之内的判断。
而我们需要对上传的文件每隔一段时间进行热点检测,相当于遍历上传文件的存储文件夹,找出所有的文件,然后通过对逐个文件进行时间差的判断,来逐个进行热点处理。
基于这个思想,我们需要将上传的文件存储位置与压缩后压缩文件的存储位置分开。这样在遍历上传文件夹的时候不至于将压缩过的文件又进行非热点处理了。
注意事项:
上传文件有自己的上传存储位置,非热点文件的压缩存储有自己的存储位置。
遍历上传存储位置文件夹,获取所有文件信息。
获取每个文件最后一次访问时间,进而完成是否热点文件的判断。
对非热点文件进行压缩存储,删除原来的未压缩文件
服务端网络通信模块与业务处理模块:
云备份项目中 ,业务处理模块是针对客户端的业务请求进行处理,并最终给与响应。而整个过程中包含以下要实现的功能:借助网络通信模块httplib 库搭建 http 服务器与客户端进行网络通信针对收到的请求进行对应的业务处理并进行响应(文件上传,列表查看,文件下载(包含断点续传))

上传:上传请求业务处理通过服务器接收到的 http 请求正文实现,  通过 MutipartFormData 中的区域标识符字段name是否为 "file" 判断上传的是否为文件, 再通过 filename 文件名字段获取备份文件名, content字段获取备份文件的内容, 通过 File_util 中的 write 接口实现备份, 添加备份信息, 成功返回 200OK 响应状态码.

查看: 查看请求业务处理通过遍历获取备份文件夹下所有备份文件的文件信息, 将文件信息组织渲染成html页面, 这里简单学了最基本的前端知识来写了个页面, 将文件名作为 /download/filename 超链接, 客户端浏览器点击该文件名即向服务点发送 /download/filename 下载文件请求. 将写好的html 页面作为响应正文返回.

下载: 下载请求业务具有断点续传功能,  断点续传: 当下载一个文件的时候,下载到中途,因为网络或者其他原因,导致下载中断, 如果第二次后边重新下载所有文件数据,效率就比较低,因为实际上之前传输的数据是不需要重新传输的如果这次下载只是从上一次断开的位置重新下载,就可以提升很高的下载效率. 

客户端数据管理模块:

客户端的数据处理模块不需要管理太多的文件数据, 只需要记录 "文件名= etag" 即可, 所以不需要json库的将信息序列化存储也就不需要按序列化这两个接口了, 当然客户端也不需要压缩解压缩接口.  File_util 的代码是linux, windows都可以复用的, 所以获取文件信息, 创建备份文件目录, 创建备份文件信息文件等直接复用 util.hpp 代码即可. 客户端的数据管理模块也是对文件信息的增删改查, 

增: 将文件放入上传备份的文件夹中, 则增加放入的文件的文件信息.

删: 和服务端一样, 作为拓展模块, 一般不需要调用删除.

改: 在判断文件是否需要上传时, 若此时文件信息和之前保存发文件信息不同了则上传, 同时更新文件存储信息.

查: 通过查询保存的文件信息etag与当前时刻的文件etag比较时使用.
 

客户端目录检查模块:

客户端的目录检索模块复用服务端 util.hpp 代码, 实现相同的功能.

客户端网络通信模块:

通过不断遍历备份文件夹中的文件, 判断其是否需要上传, 判断条件: 1. 该文件没有存储文件信息, 则说明该文件是刚放入备份文件夹的, 还没有备份上传, 需要备份. 2. 若存在备份文件信息, 则比较当前的etag与之前保存的etag比较, 若不相同则需要上传( 若最后一次访问时间与当前时间比较, 大于指定时间则认为用户已对文件修改完成, 可以上传, 否则认为用户还在修改, 先不上传, 等下次循环再判断时间是否大于, 大于则认为修改完成, 可以上传.)

需要上传则使用 httplib 搭建客户端, 通过对库中MultipartFormData 设置区域标识字段 name="file" , 文件名filename="xxx" , File_util中 Read(xxx) 读取该文件的内容到content正文中, 再将MultipartFormData结构体通过 httplib::Post()接口即可实现上传.

项目源码:登录 - Gitee.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值