1.引言
文件管理子服务实现起来比较简单,就是提供文件的上传和下载接口。也不涉及数据库表的设计,所以直接进入代码部分。
2.代码实现
**单文件下载流程:**文件的唯一标识是文件ID(file_id),所以首先提取出请求中的文件ID,明确要下载的文件,然后通过file_id去获取文件的内容,写入到响应中,返回给客户端(网关)即可。
cpp
void GetSingleFile(google::protobuf::RpcController* controller,
const ::pcz::GetSingleFileReq* request,
::pcz::GetSingleFileRsp* response,
::google::protobuf::Closure* done) {
brpc::ClosureGuard done_guard(done);
// 1.获取文件ID
std::string file_id = request->file_id();
// 2. 获取文件内容
std::string file_name = _storage_path + file_id;
std::string file_body;
if (pcz::readFile(file_name, file_body) == false) {
LOG_ERROR("下载文件失败 {}!", request->request_id());
response->set_request_id(request->request_id());
response->set_success(false);
response->set_errmsg("下载文件失败!");
return;
}
// 3.组织响应
response->set_request_id(request->request_id());
response->set_success(true);
response->mutable_file_data()->set_file_id(file_id);
response->mutable_file_data()->set_file_content(file_body);
}
单文件的上传流程:每一个文件,都需要有一个文件ID,所以首先要给上传的这个文件生成一个文件ID,然后再将文件的内容进行存储。
cpp
void PutSingleFile(google::protobuf::RpcController* controller,
const ::pcz::PutSingleFileReq* request,
::pcz::PutSingleFileRsp* response,
::google::protobuf::Closure* done) {
brpc::ClosureGuard done_guard(done);
// 1.生成文件ID,即文件名
std::string file_id = pcz::uuid();
// 2.获取文件内容并写入文件
std::string file_name = _storage_path + file_id;
std::string file_body = request->file_data().file_content();
if (pcz::writeFile(file_name, file_body) == false) {
LOG_ERROR("上传文件失败 {}!", request->request_id());
response->set_request_id(request->request_id());
response->set_success(false);
response->set_errmsg("上传文件失败!");
return;
}
// 3.组织响应
response->set_success(true);
response->set_request_id(request->request_id());
response->mutable_file_info()->set_file_id(file_id);
response->mutable_file_info()->set_file_name(request->file_data().file_name());
response->mutable_file_info()->set_file_size(request->file_data().file_size());
}
这些文件,都是保存在本地磁盘的,上传的本质就是调用系统调用write(),下载的本质就是调用系统调用read()。
3.结语
除了单文件的上传和下载外,还有多文件的上传和下载,它们本质是一样的,实现的思路也是一样的。
完