【问题标题】:Upload uint8_t* buffer to AWS S3 without going via filesystem不通过文件系统将 uint8_t* 缓冲区上传到 AWS S3
【发布时间】:2018-02-07 14:43:19
【问题描述】:

免责声明: 我不是 C++ 程序员,请救救我。

我正在尝试使用 AWS 开发工具包在 c++ 中创建一个 PutObjectRequest。

我有一个 'uint8_t*'(在 Java 领域中,我称其为字节 [],我相信在 C++ 星球上这是一个缓冲区),我需要将它放入 Aws::IOStream不知何故。

所有示例都显示了直接来自文件系统的数据。

我看到几个类似(但不是真的)问题的答案指向另一个名为 Boost 的第三方库,但是肯定这是一个常见的用例?为什么我需要第三方库来做一些使用 AWS 开发工具包才可能实现的事情?:

“我有数据,我想把它放在 S3 上。不,它不在文件系统中,是的,我在内存中创建了它。”

uint8_t* buf; //<-- How do I get this...
...
Aws::S3::Model::PutObjectRequest object_request;
object_request.WithBucket(output_bucket).WithKey(key_name);

object_request.SetBody(data); //<-- ...into here

我非常感谢这里的任何帮助或指示(不是双关语)。

更新
我已经尝试了 cmets 中的所有内容,并且:

std::shared_ptr<Aws::IOStream> objectStream = Aws::MakeShared<Aws::StringStream>("PutObjectInputStream");        
*objectStream << data;
objectStream->flush();
object_request.SetBody(objectStream);

还有这个:

std::shared_ptr<Aws::IOStream> objectStream = Aws::MakeShared<Aws::StringStream>("PutObjectInputStream");        
std::istringstream is((char*) data);
*objectStream << is.rdbuf();
objectStream->flush();
object_request.SetBody(objectStream);

编译,但每个只上传2个字节的数据。

我尝试过的其他无法编译的事情是:

auto input_data = Aws::MakeShared<Aws::IOStream>("PutObjectInputStream", std::istringstream((char*) data), std::ios_base::in | std::ios_base::binary);
object_request.SetBody(input_data);

object_request.SetBody(std::make_shared<std::istringstream>( std::istringstream( (char*) spn ) ));

这些在 S3 上创建对象,但使用 0 个字节:

    std::shared_ptr<Aws::IOStream> objectStream = Aws::MakeShared<Aws::StringStream>("PutObjectInputStream");
    objectStream->rdbuf()->pubsetbuf(static_cast<char*>(reinterpret_cast<char*>(data)), length);
    objectStream->rdbuf()->pubseekpos(length);
    objectStream->seekg(0);
    object_request.SetBody(objectStream);


    std::shared_ptr<Aws::IOStream> objectStream = Aws::MakeShared<Aws::StringStream>("PutObjectInputStream");
    objectStream->rdbuf()->pubsetbuf(reinterpret_cast<char*>(data), length);
    objectStream->rdbuf()->pubseekpos(length);
    objectStream->seekg(0);
    object_request.SetBody(objectStream);

【问题讨论】:

  • 请提供SetBody方法的参考。 First link in google 不包含它。
  • 它在 AWS 开发工具包文档中,就在这里:sdk.amazonaws.com/cpp/api/0.12.9/dd/dd8/… 抱歉,我想我已经明确表示这是一个 AWS S3 PutObjectRequest。
  • 看来你可以使用object_request.SetBody( std::istringstream( (char*) data ) ); 之类的东西,但我无法自己测试,也不确定这是最好的解决方案。
  • 感谢您的检查。不幸的是它没有编译:error: no viable conversion from 'std::istringstream' (aka 'basic_istringstream&lt;char&gt;') to 'const std::shared_ptr&lt;Aws::IOStream&gt;' (aka 'const shared_ptr&lt;basic_iostream&lt;char, std::char_traits&lt;char&gt; &gt; &gt;')
  • @ndtreviv: 不,make_shared&lt;T&gt; 不采用T 类型的参数,但需要创建TT 的构造函数的参数)。

标签: c++ amazon-web-services amazon-s3


【解决方案1】:

经过小时的黑客攻击,答案如下:

    Aws::S3::Model::PutObjectRequest object_request;
    object_request.WithBucket(output_bucket).WithKey(key_name);
    auto data = Aws::MakeShared<Aws::StringStream>("PutObjectInputStream", std::stringstream::in | std::stringstream::out | std::stringstream::binary);
    data->write(reinterpret_cast<char*>(buffer), length);
    object_request.SetBody(data);

感谢Ben Voigt 指出当您make_shared(或MakeShared 在我的情况下)时,您实际上并没有在那时将数据传递给它。你只是告诉它T你正在分享什么。

nbubis 对此问题的回答也有所帮助:const char * to std::basic_iostream

【讨论】:

  • 如果您有一个用户定义的 struct/lass 向量,则以下工作: auto data = Aws::MakeShared<:stringstream>("PutObjectInputStream", std::stringstream::in | std::stringstream::out | std::stringstream::binary);数据->write((char*)&vec[0], vec.size() * sizeof(MyData)); object_request.SetBody(data);
猜你喜欢
  • 2023-01-24
  • 2018-01-23
  • 2019-02-21
  • 1970-01-01
  • 2021-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-21
相关资源
最近更新 更多