全部文档
当前文档

暂无内容

如果没有找到您期望的内容,请尝试其他搜索词

文档中心

分块上传(C++)

最近更新时间: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;
}

文档导读
纯净模式常规模式

纯净模式

点击可全屏预览文档内容
文档反馈