aliyun / aliyun-oss-cpp-sdk

Aliyun OSS SDK for C++
Other
184 stars 88 forks source link

代价较高的 `std::shared_ptr<std::iostream>` #12

Closed yanminhui closed 5 years ago

yanminhui commented 5 years ago

提供的有关上传数据的接口参数为 std::shared_ptr<std::iostream>,如果遇上传的数据来源于程序产生,那么使用如下方式解决:

using byte_t = unsigned char;

bool COssUpload::UploadPart(int iPartNumber
                          , byte_t const* pkbyContent
                          , std::uint64_t ui64ContentLength
                          , COssError& rError)
{
    std::string const kstrContent((char*)pkbyContent
                                , static_cast<std::string::size_type>(ui64ContentLength));
    std::shared_ptr<std::iostream> piosContent = std::make_shared<std::stringstream>
                                               ( kstrContent
                                               , std::ios::in|std::ios::binary);
    return UploadPart(iPartNumber, piosContent, ui64ContentLength, rError);
}

示例中,存在损耗性能的方面:

可见,一块内存数据被反复折腾,而不是以较少代价的方式被处理。

huiguangjun commented 5 years ago

你可以继承 streambuf, 定义自己的buffer类(例如MyCharBuffer),实现相关的接口,对pkbyContent进行封装。 MyCharBuffer charBuffer(pkbyContent, ui64ContentLength); std::shared_ptr < std::iostream > charContent = std::make_shared < std::iostream > (&charBuffer);

huiguangjun commented 5 years ago

为了简化,继承std::stringbuf 作为例子。 class MyCharBuffer : public std::stringbuf { public: MyCharBuffer(char *ptr, std::streamsize size) : std::stringbuf(std::ios_base::in) { _Mysb::setg(ptr, ptr, ptr + size); _Mysb::setp(ptr + size, ptr + size, ptr + size); } };

ayumukid commented 4 years ago

class MyCharBuffer : public std::stringbuf { public: MyCharBuffer(char *ptr, std::streamsize size) : std::stringbuf(std::ios_base::in) { _Mysb::setg(ptr, ptr, ptr + size); _Mysb::setp(ptr + size, ptr + size, ptr + size); } }; 在linux 环境下编译不过

MyOssBuffer.h:12:3: 错误:‘_Mysb’未声明 _Mysb::setp(ptr + size, ptr + size, ptr + size);

ayumukid commented 4 years ago
MyOssBuffer(char *ptr, std::streamsize size):
    std::stringbuf(std::ios_base::in)
{

ifdef _WIN32

    basic_streambuf::setg(ptr, ptr, ptr + size);
    basic_streambuf::setp(ptr + size, ptr + size, ptr + size);

else

    basic_streambuf::setg(ptr, ptr, ptr + size);
    basic_streambuf::setp(ptr + size, ptr + size);

endif

}

使用这种方式 win linux下可以编译通过