最近更新时间:2024-12-05 18:44:59
以下代码用于分块上传文件:
#include "ks3.h"
#include <iostream>
#include <fstream>
// 声明读取文件内容的方法(将在代码末尾实现)
long read_file(const std::string &filename, char *buf, long offset, long len);
// 声明得到文件长度的方法(将在代码末尾实现)
long get_file_size(const std::string &filename);
using namespace ks3;
int main() {
std::string host = "ks3-cn-beijing.ksyuncs.com";
// 准备client上下文信息
// 金山云主账号 AccessKey 拥有所有API的访问权限,风险很高。
// 强烈建议您创建并使用子账号账号进行 API 访问或日常运维,请登录 https://uc.console.ksyun.com/pro/iam/#/user/list 创建子账号。
std::string ak = "yourAccessKey"; // 填写实际的AccessKey
std::string sk = "yourSecretKey"; // 填写实际的SecretKey
// 填写桶名
std::string bucket = "yourBucketName";
// 填写要上传的对象名
std::string object_key = "yourKeyName";
// 初始化网络资源
sdk::KS3Client::InitGlobalCurl();
// 初始化client
sdk::KS3Client client(host);
client.Init();
sdk::ClientContext ctx;
ctx.bucket = bucket;
ctx.object_key = object_key;
ctx.accesskey = ak;
ctx.secretkey = sk;
sdk::KS3Response response;
// 初始化分块上传
std::string uploadId;
int code = client.InitMultipartUpload(ctx, &response, &uploadId);
if (code != 0) {
std::cout << "failed to call curl with error code " << code << std::endl;
return -1;
}
if (response.status_code != 200) {
std::cout << "[ERROR] init multipart failed status_code=" << response.status_code <<
", status_ms=" << response.status_msg.c_str() << std::endl;
return -1;
}
// 上传分片
char buffer[400 * 1024];
// 获取文件大小
long file_size = get_file_size("./test.txt");
if (file_size < 0) {
std::cout << "[ERROR] load content failed" << std::endl;
return -1;
}
// 准备上传信息
long offset = 0;
int part_size = 400 * 1024;
ctx.partNum = 1;
ctx.uploadId = uploadId;
// 准备上传的块信息map
std::map<int, std::string> parts;
while (offset < file_size) {
long upload_size = (offset + part_size > file_size) ? file_size - offset : part_size;
// 将文件内容读到buffer
read_file("./test.txt", buffer, offset, upload_size);
sdk::KS3Response part_resp;
std::string etag;
code = client.UploadPart(ctx, buffer, static_cast<int>(upload_size), &part_resp, &etag);
if (code != 0) {
std::cout << "failed to call curl with error code " << code << std::endl;
return -1;
}
// 如有需要可取消分块上传
if (part_resp.status_code != 200) {
std::cout << "[ERROR] upload part " << ctx.partNum << " failed status_code=" << part_resp.status_code <<
", status_ms=" << part_resp.status_msg.c_str() << std::endl;
sdk::KS3Response abort_resp;
client.AbortMultipartUpload(ctx, &abort_resp);
return -1;
}
parts.insert(std::pair<int, std::string>(ctx.partNum, etag));
offset += upload_size;
ctx.partNum++;
}
// 列举分片
sdk::KS3Response list_resp;
std::map<int, std::string> list_parts;
code = client.ListParts(ctx, &list_parts, &list_resp);
if (code != 0) {
std::cout << "failed to call curl with error code " << code << std::endl;
return -1;
}
std::cout << list_resp.status_code << std::endl;
auto it = list_parts.begin();
for (; it != list_parts.end(); ++it) {
std::cout << it->first << ":" << it->second.c_str() << std::endl;
}
// 合并分块 - 完成分块上传
sdk::KS3Response complete_resp;
code = client.CompleteMultipartUpload(ctx, parts, &complete_resp);
if (code != 0) {
std::cout << "failed to call curl with error code " << code << std::endl;
return -1;
}
// 如有需要可取消分块上传
if (complete_resp.status_code != 200) {
std::cout << "[ERROR] complete multipart failed status_code=" << complete_resp.status_code <<
", status_ms=" << complete_resp.status_msg.c_str() << std::endl;
sdk::KS3Response abort_resp;
// 取消此次分块上传任务
client.AbortMultipartUpload(ctx, &abort_resp);
return -1;
}
sdk::KS3Client::DestroyGlobalCurl();
return 0;
}
long read_file(const std::string &filename, char *buf, long offset, long len) {
std::ifstream file(filename, std::ios::binary);
if (!file) {
std::cerr << "[ERROR] open file=" << filename << " failed" << std::endl;
return -1;
}
file.seekg(offset, std::ios::beg);
file.read(buf, len);
long rlen = file.gcount();
if (rlen != len) {
std::cerr << "[ERROR] read file=" << filename << " failed: offset=" << offset << ", len=" << len
<< ", but read len is : " << rlen << std::endl;
file.close();
return -1;
}
file.close();
return rlen;
}
long get_file_size(const std::string &filename) {
std::ifstream file(filename, std::ios::binary | std::ios::ate);
if (!file) {
std::cerr << "[ERROR] open file=" << filename << " failed" << std::endl;
return -1;
}
long len = file.tellg();
file.close();
return len;
}
纯净模式