云备份服务器
1.项目需求
客户端对指定目录下的文件进行监控,将新文件或者发生修改的文件自动上传到服务器进行备份;
服务器对上传的文件进行存储,并将非热点文件进行压缩存储,提供浏览器查看文件列表和文件断点续传下载功能;
2.开发环境
Windows客户端程序:
vs2017
Linux服务端程序:
vim、g++
3.项目模块
Windows客户端
文件监控模块:采用c++17中的文件系统接口对目录进行遍历获取文件信息
数据管理模块:记录备份的文件信息,并且通过计算文件的唯一标识符判断文件是否需要备份
文件上传模块:通过httplib库搭建http客户端,使用post请求方式实现文件上传备份。
Linux服务端
文件管理模块:对指定目录下的文件遍历判断是否为非热点文件,并进行非热点文件压缩存储
数据管理模块:记录管理备份文件信息,实现判断文件是否已经压缩的功能
HTTP服务器模块:与客户端进行交互.提供文件上传、文件列表查看、文件下载功能的处理
服务端程序启动后有两个线程,两个线程并行运行,
文件管理线程扫描备份目录下,将非热点文件进行压缩存储;
服务器线程负责处理来自Windows客户端的请求和浏览器的请求;
-
文件列表浏览:
从数据管理器中取出所有备份的文件的文件名,把文件名组织成文 件列表信息的响应正文返回给客户端; -
文件下载
首先判断要下载的文件是否存在,不存在则返回404响应;
存在进行下一步,判断文件是否被压缩,如果被压缩,执行解压缩指令;
下一步判断请求中是否有If-Range字段,
如果是拿出If-Range字段的内容,判断是否和文件当前的唯一标识相一致,不一致则从头开始传输文件,一致则说明是断点续传,将请求区间的数据写入响应体,并设置Content-Range字段和响应状态码为206;
如果是其他情况,就将请求的文件数据写入响应体,设置Content-Type字段为二进制比特流,设置Accept-Range字段为bytes,设置ETag字段为计算出的文件的唯一标识,最后设置响应状态码为200,将响应返回给浏览器 -
文件上传
将post请求的正文存储到备份目录下,并记录备份文件的信息到数据管理器中。
4.项目源码
5.项目遇到的问题
-
在客户端的数据写入模块,向一个空的容器写入数据,没有进行增容;
-
在windows平台和Linux平台存在字符编码的转换问题;
-
在将数据写入配置文件时,不能使用\n分割每一条数据,因为文件中可能会有换行,所以选择使用不可见字符\5进行间隔;
-
ETag字段的值因为有特殊符号,所以在设置时没有设置成功,导致断点续传失败,通过将计算出来的ETag值进行转换,把特殊符号统一转换为空格;
-
采用bundle库进行压缩需要将数据放入内存,虚拟机之前的运行内存太小,所以运行报错,需要比较大的运行内存;
6.项目特点
线程池、读写锁、断点续传、zip压缩、C++17filesystem
7.面试被问到的点
1)同名文件是如何处理的?
当前采用同名文件覆盖的方式,因为只有一个用户;
后期如果是多用户会采用不同用户不同文件夹进行区分;
2)文件上传或者下载过程中,如果文件被删除如何处理?
采用文件锁对读写的文件进行加锁保护,防止操作过程中文件被删除或者修改