C++ S3Client::SetRange的GetObject返回错误的数据?
我正在尝试读取一个大型AWS S3对象的一段,从第一个1048576字节开始。我指定了要读取的字节范围,但没有收到这些字节。返回的长度是正确的 我在这方面比较新,所以我可能做了一些错误,作为C程序员而不是C++没有太大帮助。 以下是我的代码示例: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
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::coutrdbuf()
是一个流,您将其视为内存指针。这是我的最终代码,供感兴趣的人参考。如果您认为合适,我也将非常感谢您的评论
#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);