5. 文件下载

S3 CPP SDK提供了丰富的文件下载接口,用户可以通过以下方式从NOS获取文件:

  • 下载文件到内存
  • 下载到本地文件
  • 分段下载
  • 条件下载

5.1. 下载文件到内存

以下源代码实现下载文件到内存中:

void getObjectAndShowContent(const Aws::S3::S3Client& s3Client,const Aws::String& bucketName,const Aws::String& objectName){
    Aws::S3::Model::GetObjectRequest object_request;
    object_request.WithBucket(bucketName).WithKey(objectName);

    auto get_object_outcome = s3Client.GetObject(object_request);

    if (get_object_outcome.IsSuccess())
    {
        std::cout  << get_object_outcome.GetResult().GetBody().rdbuf() << std::endl;
        std::cout << "Done!" << std::endl;
    }
    else
    {
        std::cout << "GetObject error: " <<
        get_object_outcome.GetError().GetExceptionName() << " " <<
        get_object_outcome.GetError().GetMessage() << std::endl;
    }

}

5.2. 下载文件到本地文件

以下源代码实现将NOS文件下载到本地文件:

void downloadObject(const Aws::S3::S3Client& s3Client,const Aws::String& bucketName,const Aws::String& objectName,const Aws::String& saveName){
    Aws::S3::Model::GetObjectRequest object_request;
    object_request.WithBucket(bucketName).WithKey(objectName);

    auto get_object_outcome = s3Client.GetObject(object_request);

    if (get_object_outcome.IsSuccess())
    {
        Aws::OFStream local_file;
        local_file.open(saveName.c_str(), std::ios::out | std::ios::binary);
        local_file << get_object_outcome.GetResult().GetBody().rdbuf();
        std::cout << "Done!" << std::endl;
    }
    else
    {
        std::cout << "GetObject error: " <<
        get_object_outcome.GetError().GetExceptionName() << " " <<
        get_object_outcome.GetError().GetMessage() << std::endl;
    }

}

5.3. 指定范围下载

如果存储在NOS中的文件较大,并且您只需要其中的一部分内容,您可以使用范围下载,下载指定范围的数据,如果指定的下载范围为”0-100”,则返回结果为第0字节到第100字节的数据,返回的数据包含第100字节, 即range=0-100,如果指定的范围无效则下载整个文件,以下源代码获取range=0-100字节的内容:

void getObjectByRangeAndShowContent(const Aws::S3::S3Client& s3Client,const Aws::String& bucketName,const Aws::String& objectName){
    Aws::S3::Model::GetObjectRequest object_request;
    object_request.WithBucket(bucketName).WithKey(objectName).WithRange("bytes=0-100");


    auto get_object_outcome = s3Client.GetObject(object_request);

    if (get_object_outcome.IsSuccess())
    {
        std::cout  << get_object_outcome.GetResult().GetBody().rdbuf() << std::endl;
        std::cout << "Done!" << std::endl;
    }
    else
    {
        std::cout << "GetObject error: " <<
        get_object_outcome.GetError().GetExceptionName() << " " <<
        get_object_outcome.GetError().GetMessage() << std::endl;
    }

}

Attention

  1. 下载内容也可以存储到文件中
  2. 注意下载的区间为闭区间

5.4. 条件下载

下载文件时,可以指定限定条件,满足限定条件时下载,不满足时报错,不下载文件。可以使用的限定条件如下:

参数 说明 GetObjectRequest对应值
If-Modified-Since 如果指定的时间早于实际修改时间,则正常传送。否则返回错误 GetObjectRequest.IfModifiedSince

代码示例如下:

void getObjectByIfModifiedSinceAndShowContent(const Aws::S3::S3Client& s3Client,const Aws::String& bucketName,const Aws::String& objectName){
    Aws::S3::Model::GetObjectRequest object_request;
    //一个小时前到现在是否别修改过,如果被修改过,那么就返回,负责返回304 Not Modified
    object_request.WithBucket(bucketName).WithKey(objectName).WithIfModifiedSince(Aws::Utils::DateTime(Aws::Utils::DateTime::CurrentTimeMillis() - 1000*60*60));


    auto get_object_outcome = s3Client.GetObject(object_request);

    if (get_object_outcome.IsSuccess())
    {
        std::cout  << get_object_outcome.GetResult().GetBody().rdbuf() << std::endl;
        std::cout << "Done!" << std::endl;
    }
    else
    {
        std::cout << "GetObject error: " <<
        get_object_outcome.GetError().GetExceptionName() << " " <<
        get_object_outcome.GetError().GetMessage() << std::endl;
    }

}