数据管理模块设计之前,我们需要先明确该模块的信息是用来做什么的。根据上文分析该模块信息主要用于判断一个文件是否需要备份,判断条件有两个:1.新增文件 2.被修改过的文件
新增文件好判断,由于我们获得新文件后是先上传文件,再将文件信息插入到数据管理模块中,模块里没有存储该文件信息,则该文件为新增文件
而第二个判断修改文件,我们会设定一个文件的唯一标识,类似于之前服务端构建http协议的ETag关键字,该标识由 文件名-文件大小-文件最后一次修改时间 构成
由上可得,我们文件信息表中需要存储的信息只有两个:文件名-唯一标识
因此内存中存储文件信息表我们选择用unordered_map存储这对KV(文件名-文件唯一标识)值
而对于持久化存储,关键点在于自己完成序列化和反序列化,不过由于存储信息简单因此序列化和反序列化也比较简单,我们序列化方式如下
反序列化则是写一个字符串拆分函数,先拆除一个一个的KV键值对,在将KV值分离
因此,我们接口设置如下
- #pragma once
- #include "util.hpp"
- #include
- namespace mjw_cloud
- {
- class FileDatas
- {
- public:
- FileDatas(const std::string& backup_file)
- :_backup_file(backup_file)
- {}
-
- bool InitTable()
- {}
- bool Storage()
- {}
- bool Insert(const std::string& key, const std::string& val)
- {}
- bool Updata(const std::string& key, const std::string& val)
- {}
- bool GetoneByKey(const std::string& key, std::string* val)
- {}
- private:
- //解析序列化字符串时需要
- //字符串分割,对序列化字符串进行分割
- //"key val key" -> "key" "val" "key"
- int Split(const std::string& str, const std::string& seq, std::vector
* arry) - {}
- private:
- std::unordered_map
_table;//文件信息表 - std::string _backup_file;//备份文件信息 存储文件
- };
- }
代码实现如下:
- #pragma once
- #include "util.hpp"
- #include
- namespace mjw_cloud
- {
- class FileDatas
- {
- public:
- FileDatas(const std::string& backup_file)
- :_backup_file(backup_file)
- {
-
- InitTable();
- }
-
- bool InitTable()
- {
- //1.从文件中读取备份文件信息序列化字符串
- std::string body;
- FileUtil fu(_backup_file);
- fu.GetContent(&body);
- if (body.empty()) return true;
- //2.对字符串进行反序列化解析
- std::vector
arry; - //"key val\nkey val\n" -> "key val" "key val"
- Split(body, "\n", &arry);
- for (auto a : arry)
- {
- std::vector
tmp; - //"key val" -> "key" "val"
- Split(a, " ", &tmp);
- if (tmp.size() != 0) continue;
- _table[tmp[0]] = tmp[1];
- }
- return true;
- }
- bool Storage()
- {
- if (_table.empty()) return true;
- //1.构建序列化字符串
- std::string body;
- for (auto& t : _table)
- {
- body += t.first + " " + t.second + "\n";
- }
- //2.将字符串写入指定文件
- FileUtil fu(_backup_file);
- fu.SetContent(body);
- return true;
- }
- bool Insert(const std::string& key, const std::string& val)
- {
- _table[key] = val;
- return true;
- }
- bool Updata(const std::string& key, const std::string& val)
- {
- _table[key] = val;
- return true;
- }
- bool GetoneByKey(const std::string& key, std::string* val)
- {
- auto it = _table.find(key);
- if (it == _table.end())
- {
- return false;
- }
- *val = _table[key];
- return true;
- }
- private:
- //解析序列化字符串时需要
- //字符串分割,对序列化字符串进行分割
- //"key val key" -> "key" "val" "key"
- int Split(const std::string& str, const std::string& seq, std::vector
* arry) - {
- int count = 0;
- int pos = 0, idx = 0;
- while (idx < str.size())
- {
- pos = str.find(seq, idx);
- if (pos == std::string::npos) break;
- arry->push_back(str.substr(idx, pos - idx));
- idx = pos + 1;
- count++;
- }
-
- if (idx < str.size())
- {
- //说明str还有最后一截字符串没有push_back进arry
- arry->push_back(str.substr(idx));
- count++;
- }
- return count;
- }
- private:
- std::unordered_map
_table;//文件信息表 - std::string _backup_file;//备份文件信息 存储文件
- };
- }