0

使用 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();
    }
}

这些是 S3ReadableFile 类的私有成员

    std::shared_ptr<Aws::S3::S3Client> s3Client;
    std::string bucketName;
    std::string key;
    size_t position;
    bool valid;
4

2 回答 2

2

Range 的值应为“bytes=0-4” 参见:https ://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35

于 2018-03-28T18:42:14.117 回答
0

确保你不要在下面做,

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

我花了很长时间才弄清楚!

于 2020-03-17T22:42:20.097 回答