AWS s3 cpp sdk 读取的字节数超过指定范围
AWS s3 cpp sdk reading more bytes than range specified
使用 AWS s3 cpp sdk,我们尝试使用以下代码从存储桶中读取数据。当我们使用
指定一个小范围时
Aws::S3::Model::GetObjectRequest object_request;
object_request.SetRange(std::to_string(position) + "-" + std::to_string(position + nbytes));
因此,开始位置为 0,结束位置为 4。我们发现读取操作实际上读取的字节数比我们分配到缓冲区中的字节数更多。所以我们有一个 69 字节长的文件。如果我们尝试从中读取前 4 个字节,则返回的结果是
auto results = this->s3Client->GetObject(object_request);
我们发现从服务器实际读取的大小是69字节。文件的整个大小。当您指定非常小的操作时,SDK 是否会尝试读取最小值?这个值是否记录在某处?
这是下面尝试从 s3 读取数据的实际函数。
arrow::Status S3ReadableFile::Read(int64_t nbytes, int64_t* bytesRead, uint8_t* buffer) {
Aws::S3::Model::GetObjectRequest object_request;
object_request.SetBucket(bucketName);
object_request.SetKey(key);
object_request.SetRange(std::to_string(position) + "-" + std::to_string(position + nbytes));
auto results = this->s3Client->GetObject(object_request);
if (!results.IsSuccess()) {
//TODO: Make bad arrow status here
*bytesRead = 0;
return arrow::Status::IOError("Unable to fetch object from s3 bucket.");
} else {
//byutes read should always be full amount
*bytesRead = nbytes; //should almost always be nBytes
memcpy(buffer, results.GetResult().GetBody().rdbuf(), *bytesRead);
position += *bytesRead;
return arrow::Status::OK();
}
}
这些是 class S3ReadableFile
的私有成员
std::shared_ptr<Aws::S3::S3Client> s3Client;
std::string bucketName;
std::string key;
size_t position;
bool valid;
Range 的值应该是 "bytes=0-4"
参见:https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35
请确保您没有执行以下操作,
# wrong way of using ss
std::stringstream ss("bytes=");
ss << beg << '-' << end;
object_request.SetRange(ss.str().c_str());
假设beg为0,end为10,
这将不起作用,因为它将 0-10
传递给 SDK。如果它不符合 https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35,即 bytes=0-10
,它将下载所有字节。
正确的是
std::stringstream ss();
ss << "bytes=" << beg << '-' << end;
object_request.SetRange(ss.str().c_str());
我想了半天!
使用 AWS s3 cpp sdk,我们尝试使用以下代码从存储桶中读取数据。当我们使用
指定一个小范围时Aws::S3::Model::GetObjectRequest object_request;
object_request.SetRange(std::to_string(position) + "-" + std::to_string(position + nbytes));
因此,开始位置为 0,结束位置为 4。我们发现读取操作实际上读取的字节数比我们分配到缓冲区中的字节数更多。所以我们有一个 69 字节长的文件。如果我们尝试从中读取前 4 个字节,则返回的结果是
auto results = this->s3Client->GetObject(object_request);
我们发现从服务器实际读取的大小是69字节。文件的整个大小。当您指定非常小的操作时,SDK 是否会尝试读取最小值?这个值是否记录在某处?
这是下面尝试从 s3 读取数据的实际函数。
arrow::Status S3ReadableFile::Read(int64_t nbytes, int64_t* bytesRead, uint8_t* buffer) {
Aws::S3::Model::GetObjectRequest object_request;
object_request.SetBucket(bucketName);
object_request.SetKey(key);
object_request.SetRange(std::to_string(position) + "-" + std::to_string(position + nbytes));
auto results = this->s3Client->GetObject(object_request);
if (!results.IsSuccess()) {
//TODO: Make bad arrow status here
*bytesRead = 0;
return arrow::Status::IOError("Unable to fetch object from s3 bucket.");
} else {
//byutes read should always be full amount
*bytesRead = nbytes; //should almost always be nBytes
memcpy(buffer, results.GetResult().GetBody().rdbuf(), *bytesRead);
position += *bytesRead;
return arrow::Status::OK();
}
}
这些是 class S3ReadableFile
的私有成员 std::shared_ptr<Aws::S3::S3Client> s3Client;
std::string bucketName;
std::string key;
size_t position;
bool valid;
Range 的值应该是 "bytes=0-4" 参见:https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35
请确保您没有执行以下操作,
# wrong way of using ss
std::stringstream ss("bytes=");
ss << beg << '-' << end;
object_request.SetRange(ss.str().c_str());
假设beg为0,end为10,
这将不起作用,因为它将 0-10
传递给 SDK。如果它不符合 https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35,即 bytes=0-10
,它将下载所有字节。
正确的是
std::stringstream ss();
ss << "bytes=" << beg << '-' << end;
object_request.SetRange(ss.str().c_str());
我想了半天!