S3Client :: GetObject с SetRange возвращает неверные данные? - PullRequest
1 голос
/ 30 мая 2019

Я пытаюсь прочитать сегмент большого объекта 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);

Затем я дам дамп буфера bdata, и это не то, что я ожидал.Когда я повторяю выполнение кода нового экземпляра, он возвращает разные данные.

Хотя я не показываю это, буферу bdata предварительно выделено 2 мегабайта.

Любые идеи, которыебудет указывать мне в правильном направлении будет признателен.

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 31 мая 2019

Вот мой окончательный код для тех, кто заинтересован. Буду также признателен за любые комментарии, которые вы считаете целесообразными.

#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);
}

Я уверен, что это можно сделать более эффективным способом, и, надеюсь, я научусь этому по мере продвижения вперед.

1 голос
/ 30 мая 2019

rdbuf() - это поток, и вы рассматриваете его как указатель памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...