Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ S3Client::SetRange的GetObject返回错误的数据?_C++_Amazon Web Services_Amazon S3 - Fatal编程技术网

C++ S3Client::SetRange的GetObject返回错误的数据?

C++ S3Client::SetRange的GetObject返回错误的数据?,c++,amazon-web-services,amazon-s3,C++,Amazon Web Services,Amazon S3,我正在尝试读取一个大型AWS S3对象的一段,从第一个1048576字节开始。我指定了要读取的字节范围,但没有收到这些字节。返回的长度是正确的 我在这方面比较新,所以我可能做了一些错误,作为C程序员而不是C++没有太大帮助。 以下是我的代码示例: int start=0, rbytes=0; Aws::S3::S3Client s3_client; Aws::S3::Model::GetObjectRequest read_object_request; sprintf(range,"b

我正在尝试读取一个大型AWS S3对象的一段,从第一个1048576字节开始。我指定了要读取的字节范围,但没有收到这些字节。返回的长度是正确的

我在这方面比较新,所以我可能做了一些错误,作为C程序员而不是C++没有太大帮助。 以下是我的代码示例:

int   start=0, rbytes=0;

Aws::S3::S3Client  s3_client;
Aws::S3::Model::GetObjectRequest read_object_request;
sprintf(range,"bytes=%lld-%lld",start,start+1048575);

read_object_request.SetBucket(container_name);
read_object_request.SetKey(object_name);
read_object_request.SetRange(range);
auto results = s3_client.GetObject(read_object_request);
if (results.IsSuccess())
{
   rbytes = results.GetResult().GetContentLength();
   std::cout << rbytes << " bytes read" << std::endl;
}
memcpy(bdata,results.GetResult().GetBody().rdbuf(),rbytes);
int start=0,rbytes=0;
Aws::S3::S3客户端S3_客户端;
Aws::S3::Model::GetObjectRequest读取对象请求;
sprintf(范围,“字节=%lld-%lld”,开始,开始+1048575);
读取对象请求SetBucket(容器名称);
读取对象请求.SetKey(对象名称);
读取对象请求。设置范围(范围);
自动结果=s3\u client.GetObject(读取对象请求);
if(results.issucess())
{
rbytes=results.GetResult().GetContentLength();

std::cout
rdbuf()
是一个流,您将其视为内存指针。

这是我的最终代码,供感兴趣的人参考。如果您认为合适,我也将非常感谢您的评论

#include <streambuf>
#include <aws/core/Aws.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/GetObjectRequest.h>
#include <aws/s3/model/HeadObjectRequest.h>
#include <aws/s3/model/HeadObjectResult.h>
#include <aws/s3/model/Object.h>

long scanObject(Aws::String region,
                Aws::String bucket_name,
                Aws::String object_name);


int main(int argc, char** argv)
{
   long scanned=0;

   if (argc < 4){ return(1); }
   Aws::String region = argv[1];
   Aws::String bucket_name = argv[2];
   Aws::String object_name = argv[3];

   Aws::SDKOptions options;
   Aws::InitAPI(options);

   scanned = scanObject(region,bucket_name,object_name);
   printf("Scanned %d bytes of object\n",scanned);

   Aws::ShutdownAPI(options);

   return(0);
}

long scanObject(Aws::String region,
                Aws::String bucket_name,
                Aws::String object_name)
{
   int   rbytes, nbytes;
   char range[48], *buffer;
   long filesize, bytesleft, start;

   Aws::Client::ClientConfiguration cconfig;
   cconfig.region = region;
   Aws::S3::S3Client s3_client(cconfig);

   Aws::S3::Model::HeadObjectRequest head_object_request;
   head_object_request.WithBucket(bucket_name).WithKey(object_name);
   Aws::S3::Model::HeadObjectOutcome head_object;
   head_object = s3_client.HeadObject(head_object_request);
   if (!head_object.IsSuccess())
   {
      printf("AWS Object, /%s/%s, failed to locate\n",
             region.c_str(),object_name.c_str());
      return(-1);
   }

   filesize = head_object.GetResult().GetContentLength();
   bytesleft = filesize;

   start = 0;
   nbytes = 1048576;
   buffer = (char*)malloc(nbytes*2);

   Aws::S3::Model::GetObjectRequest read_request;
   while(bytesleft > 0)
   {
      if (bytesleft > 1048576){ nbytes = 1048576; }else{ nbytes = bytesleft; }

      sprintf(range,"bytes=%d-%d",start,start+nbytes-1);

      read_request.SetBucket(bucket_name);
      read_request.SetKey(object_name);
      read_request.SetRange(range);

      auto results = s3_client.GetObject(read_request);

      if (!results.IsSuccess())
      {
         printf("\nUnable to fetch object range %s from s3 bucket.\n",range);
         return(-1);
      }
      rbytes = results.GetResult().GetContentLength();

      std::streambuf* body = results.GetResult().GetBody().rdbuf();
      body->sgetn(buffer,rbytes);

      start += rbytes;
      bytesleft -= rbytes;
   }

   return(filesize);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
长扫描对象(Aws::字符串区域,
Aws::字符串bucket_name,
Aws::字符串对象(名称);
int main(int argc,字符**argv)
{
长扫描=0;
if(argc<4){返回(1);}
Aws::String region=argv[1];
Aws::String bucket_name=argv[2];
Aws::String object_name=argv[3];
Aws::SDK选项;
Aws::InitAPI(选项);
扫描=扫描对象(区域、存储桶名称、对象名称);
printf(“已扫描%d字节的对象\n”,已扫描);
Aws::关闭API(选项);
返回(0);
}
长扫描对象(Aws::字符串区域,
Aws::字符串bucket_name,
Aws::字符串对象(名称)
{
int红细胞,n红细胞;
字符范围[48],*缓冲区;
长文件大小,字节左,开始;
Aws::Client::客户端配置cconfig;
cconfig.region=区域;
Aws::S3::S3客户端S3_客户端(cconfig);
Aws::S3::Model::HeadObjectRequest头对象请求;
head\u object\u request.WithBucket(bucket\u name)。WithKey(object\u name);
Aws::S3::Model::HeadObjectOutput头_对象;
head\u object=s3\u client.HeadObject(head\u object\u请求);
如果(!head\u object.issucess())
{
printf(“AWS对象,/%s/%s,未能定位\n”,
region.c_str(),object_name.c_str();
返回(-1);
}
filesize=head_object.GetResult().GetContentLength();
bytesleft=文件大小;
开始=0;
n字节=1048576;
缓冲区=(字符*)malloc(n字节*2);
Aws::S3::Model::GetObjectRequest读取请求;
while(字节左>0)
{
如果(bytesleet>1048576){nbytes=1048576;}否则{nbytes=bytesleet;}
sprintf(范围,“字节=%d-%d”,开始,开始+nbytes-1);
read\u request.SetBucket(bucket\u name);
read_request.SetKey(对象名称);
读取请求。设置范围(范围);
自动结果=s3\u client.GetObject(读取请求);
如果(!results.issucess())
{
printf(“\n无法从s3存储桶获取对象范围%s。\n”,范围);
返回(-1);
}
rbytes=results.GetResult().GetContentLength();
std::streambuf*body=results.GetResult().GetBody().rdbuf();
体->sgetn(缓冲液,红细胞);
起始+=红细胞;
字节左-=红细胞;
}
返回(文件大小);
}

<>我确信这是可以更有效地完成的,希望我会在学习过程中了解到。

尝试通过使用AWSCLI(AWS S3API获取对象——范围=“字节=1-20”…)运行等效的远程获取来确定它是否是C++代码的问题。。我会针对已知文本文件的前20个字节运行此代码和您的代码以进行测试。谢谢,我真的应该在发布之前这样做。我使用了aws cli,它确实下载了请求的范围。我认为您需要从读取缓冲区流式传输到字符串或字节数组。例如(如果它是文本文件):Aws::StringStream ss;ss您是对的,谢谢。您的回复让我进行了另一次搜索并得到了一个工作结果。非常感谢。我需要在我控制的缓冲区中进行输出,所以我做了以下操作:streambuf*body=results.GetResult().GetBody().rdbuf();body->sgetn(缓冲区,rbytes);