C++ [aws sdk cpp][s3]使用getObject下载二进制文件

C++ [aws sdk cpp][s3]使用getObject下载二进制文件,c++,amazon-s3,download,binary-data,aws-sdk-cpp,C++,Amazon S3,Download,Binary Data,Aws Sdk Cpp,我正在尝试编写一些代码从AWSS3服务器下载二进制文件 我在下面写了这段代码,大约200MB的二进制文件看起来还可以,所以我认为它可以工作 但对于像200MB~这样的大文件,可以下载,但只能下载文件的前端部分 例如,一个视频文件(1.2GB)只下载前端(460MB~700MB) 为什么会发生这种情况?这是关于流特征的吗 // 3. file download from s3 { string strTargetPath = hThis->m_strTargetPath; A

我正在尝试编写一些代码从AWSS3服务器下载二进制文件

我在下面写了这段代码,大约200MB的二进制文件看起来还可以,所以我认为它可以工作

但对于像200MB~这样的大文件,可以下载,但只能下载文件的前端部分

例如,一个视频文件(1.2GB)只下载前端(460MB~700MB)

为什么会发生这种情况?这是关于流特征的吗

// 3. file download from s3
{
    string strTargetPath = hThis->m_strTargetPath;
    Aws::SDKOptions options;
    options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Trace;
    Aws::InitAPI(options);
    {
        // Download from s3 using GetObject

        char *bucket_name = "mybucket";
        std::string key_name = strTargetPath;

        Aws::Client::ClientConfiguration clientConfig;
        clientConfig.region = "ap-northeast-2";

        //Aws::S3::S3Client s3_client;
        std::unique_ptr< Aws::S3::S3Client > s3_client(new Aws::S3::S3Client(clientConfig));
        Aws::S3::Model::GetObjectRequest object_request;
        object_request.WithBucket(bucket_name).WithKey(key_name.c_str());

        // parse file name from path
        string str_arr[1000];
        int str_cnt = 0;

        char *str_buff = new char[1000];
        strcpy(str_buff, strTargetPath.c_str());

        char *tok = strtok(str_buff, "/");
        while (tok != nullptr) {
            str_arr[str_cnt++] = string(tok);
            tok = strtok(nullptr, "/");
        }

        string fileName = str_arr[str_cnt - 1];

        auto get_object_outcome = s3_client.get()->GetObject(object_request);

        if (get_object_outcome.IsSuccess())
        {
            Aws::OFStream local_file;
            std::string strFileName = fileName;
            hThis->m_origFileNameString = strFileName;
            hThis->m_origFileName = strFileName.c_str();

            // Writing file downloaded
            local_file.open(hThis->m_origFileName, std::ios::out | std::ios::binary);
            local_file << get_object_outcome.GetResult().GetBody().rdbuf();
            hThis->Logger(CPrePackagerDlg::currentDateTime() + "download is done\n");

            TCHAR programpath[_MAX_PATH];
            GetCurrentDirectory(_MAX_PATH, programpath);
            hThis->m_valOriginFolderPath.Format(_T("%s\\"), programpath);
            hThis->m_valOriginFolderPath += hThis->m_origFileName;
        }
        else
        {
            hThis->Logger(CPrePackagerDlg::currentDateTime() + "s3 download error: " +
                get_object_outcome.GetError().GetExceptionName() + " " +
                get_object_outcome.GetError().GetMessage() + "\n");
            hThis->runSignal = CPrePackagerDlg::RunSignal::STAT_RUN_STOP;
        }


    }
    Aws::ShutdownAPI(options);

}
//3。从s3下载文件
{
字符串strTargetPath=hThis->m_strTargetPath;
Aws::SDK选项;
options.loggingOptions.logLevel=Aws::Utils::Logging::logLevel::Trace;
Aws::InitAPI(选项);
{
//使用GetObject从s3下载
char*bucket_name=“mybucket”;
std::string key_name=strTargetPath;
Aws::Client::ClientConfiguration clientConfig;
clientConfig.region=“ap-northeast-2”;
//Aws::S3::S3客户端S3_客户端;
std::unique_ptrS3_客户端(新的Aws::S3::S3Client(clientConfig));
Aws::S3::Model::GetObjectRequest对象_请求;
object_request.WithBucket(bucket_name).WithKey(key_name.c_str());
//从路径解析文件名
字符串str_arr[1000];
int str_cnt=0;
char*str_buff=新字符[1000];
strcpy(str_buff,strTargetPath.c_str());
char*tok=strtok(str_buff,“/”);
while(tok!=nullptr){
str_arr[str_cnt++]=字符串(tok);
tok=strtok(nullptr,“/”);
}
字符串文件名=str_arr[str_cnt-1];
自动获取对象结果=s3\u客户端.get()->GetObject(对象请求);
if(get_object_outcome.issucess())
{
Aws::of流本地_文件;
std::string strFileName=文件名;
hThis->m_origFileNameString=strFileName;
hThis->m_origFileName=strFileName.c_str();
//已下载写入文件
local_file.open(hThis->m_origFileName,std::ios::out | std::ios::binary);
本地_文件记录器(CPrePackagerDlg::currentDateTime()+“下载完成\n”);
TCHAR程序路径[_MAX_PATH];
GetCurrentDirectory(_MAX_PATH,programpath);
hThis->m_valOriginFolderPath.Format(\u T(“%s\\”),programpath);
hThis->m_valOriginFolderPath+=hThis->m_origFileName;
}
其他的
{
hThis->Logger(CPrePackagerDlg::currentDateTime()+“s3下载错误:”+
获取对象结果。GetError().GetExceptionName()+“”+
获取对象\u结果。GetError().GetMessage()+“\n”);
hThis->runSignal=CPrePackagerDlg::runSignal::STAT\u RUN\u STOP;
}
}
Aws::关闭API(选项);
}

即使是现在,我也不知道它为什么不起作用

但我将我的方法改为如下,它成功了


此代码使下载的区块数据直接发送到光盘

所以它不会占用太多内存。(大约10~30MB)

//3。从s3下载文件
{
字符串strTargetPath=hThis->m_strTargetPath;
Aws::SDK选项;
options.loggingOptions.logLevel=Aws::Utils::Logging::logLevel::Trace;
Aws::InitAPI(选项);
{
//使用GetObject从s3下载
char*bucket_name=“nemodax upload dev”;
std::string key_name=strTargetPath;
Aws::Client::ClientConfiguration clientConfig;
clientConfig.region=“ap-northeast-2”;
//Aws::S3::S3客户端S3_客户端;
std::unique_ptrS3_客户端(新的Aws::S3::S3Client(clientConfig));
Aws::S3::Model::GetObjectRequest对象_请求;
object_request.WithBucket(bucket_name).WithKey(key_name.c_str());
//从路径解析文件名
字符串str_arr[1000];
int str_cnt=0;
char*str_buff=新字符[1000];
strcpy(str_buff,strTargetPath.c_str());
char*tok=strtok(str_buff,“/”);
while(tok!=nullptr){
str_arr[str_cnt++]=字符串(tok);
tok=strtok(nullptr,“/”);
}
字符串文件名=str_arr[str_cnt-1];
// 다운로드하면서 스트림을 아래 文件名으로 지정하는 파일로 바로바로 저장 그래서 메모리를 별로 안먹는다.
对象\u request.SetResponseStreamFactory(
[=]() {
//返回Aws::New(“S3DOWNLOAD”,hThis->m_origFileName,std::ios_base::out | std::ios_base::binary);
返回Aws::New(“S3DOWNLOAD”,文件名,std::ios_base::out | std::ios_base::binary);
}
);
自动获取对象结果=s3\u客户端.get()->GetObject(对象请求);
if(get_object_outcome.issucess())
{
std::string strFileName=文件名;
hThis->m_origFileNameString=strFileName;
hThis->m_origFileName=strFileName.c_str();
hThis->Logger(CPrePackagerDlg::currentDateTime()+“文件大小:”+std::to_字符串(get_object\u output.GetResult().GetContentLength())+“\n”);
hThis->Logger(CPrePackagerDlg::currentDateTime()+“下载完成\n”);
// 다운로드된 원본 파일 경로를 멤버변수로 등록-> 추후 암호화때 이 경로를 참조함.
// 파일경로 + 파일명 조합
TCHAR程序路径[_MAX_PATH];
GetCurrentDirectory(_MAX_PATH,programpath);
hThis->m_valOriginFolderPath.Format(\u T(“%s\\”),programpath);
hThis->m_valOriginFolderPath+=hThis->m_orig
// 3. file download from s3
   {
          string strTargetPath = hThis->m_strTargetPath;
          Aws::SDKOptions options;
          options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Trace;
          Aws::InitAPI(options);
          {
                 // Download from s3 using GetObject

                 char *bucket_name = "nemodax-upload-dev";
                 std::string key_name = strTargetPath;
                 Aws::Client::ClientConfiguration clientConfig;
                 clientConfig.region = "ap-northeast-2";
                 //Aws::S3::S3Client s3_client;
                 std::unique_ptr< Aws::S3::S3Client > s3_client(new Aws::S3::S3Client(clientConfig));
                 Aws::S3::Model::GetObjectRequest object_request;
                 object_request.WithBucket(bucket_name).WithKey(key_name.c_str());

                 // parse file name from path
                 string str_arr[1000];
                 int str_cnt = 0;
                 char *str_buff = new char[1000];
                 strcpy(str_buff, strTargetPath.c_str());
                 char *tok = strtok(str_buff, "/");
                 while (tok != nullptr) {
                       str_arr[str_cnt++] = string(tok);
                       tok = strtok(nullptr, "/");
                 }
                 string fileName = str_arr[str_cnt - 1];
                 // 다운로드하면서 스트림을 아래 fileName으로 지정하는 파일로 바로바로 저장 그래서 메모리를 별로 안먹는다.
                 object_request.SetResponseStreamFactory(
                       [=]() {
                       //return Aws::New<Aws::FStream>("S3DOWNLOAD", hThis->m_origFileName, std::ios_base::out | std::ios_base::binary);
                       return Aws::New<Aws::FStream>("S3DOWNLOAD", fileName, std::ios_base::out | std::ios_base::binary);
                 }
                 );
                 auto get_object_outcome = s3_client.get()->GetObject(object_request);
                 if (get_object_outcome.IsSuccess())
                 {
                       std::string strFileName = fileName;
                       hThis->m_origFileNameString = strFileName;
                       hThis->m_origFileName = strFileName.c_str();
                       hThis->Logger(CPrePackagerDlg::currentDateTime() + "file size: " + std::to_string(get_object_outcome.GetResult().GetContentLength()) + "\n");
                       hThis->Logger(CPrePackagerDlg::currentDateTime() + "download is done\n");
                       // 다운로드된 원본 파일 경로를 멤버변수로 등록-> 추후 암호화때 이 경로를 참조함.
                       // 파일경로 + 파일명 조합
                       TCHAR programpath[_MAX_PATH];
                       GetCurrentDirectory(_MAX_PATH, programpath);
                       hThis->m_valOriginFolderPath.Format(_T("%s\\"), programpath);
                       hThis->m_valOriginFolderPath += hThis->m_origFileName;
                 }
                 else
                 {
                       hThis->Logger(CPrePackagerDlg::currentDateTime() + "s3 download error: " +
                              get_object_outcome.GetError().GetExceptionName() + " " +
                              get_object_outcome.GetError().GetMessage() + "\n");
                       hThis->runSignal = CPrePackagerDlg::RunSignal::STAT_RUN_STOP;
                 }

          }
          Aws::ShutdownAPI(options);
   }