簡體   English   中英

如何從uint8_t向量創建istream?

[英]How can i create a istream from a uint8_t vector?

我正在添加通過網絡獲取數據的能力,以便只讀取本地文件的代碼。 我正在使用的網絡庫以vector<uint8_t>的形式發送和接收數據。 我希望能夠在讀取文件后重用處理數據的代碼,但該代碼需要std :: istream,有沒有辦法讓istream讀取矢量數據? 這是相同的數據,所以我覺得應該有辦法,但我無法找到或找出如何做的代碼。

當前代碼:

    std::ifstream stream("data.img", std::ios::in | std::ios::binary | std::ios::ate);

    if (!stream.is_open())
    {
        throw std::invalid_argument("Could not open file.");
    }
    // the arg for processData is std::istream
    processData(stream);

網絡框架:

    vector<uint8_t> data = networkMessage.data;

    // need some way to create istream from data
    std::istream stream = ?

    processData(stream);
    stream.close();

有沒有辦法做到這一點,還是我咆哮錯誤的樹?

std::basic_istream從關聯的std::basic_streambuf派生類中獲取其數據。 STL為文件I / O和字符串I / O提供此類,但不為內存I / O或網絡I / O提供此類。

您可以輕松編寫(或找到第三方)基於內存的streambuf類,它使用std::vector作為其底層緩沖區,然后您可以構造一個使用該內存streambufstd::istream 例如(使用此答案中imemstream類):

std::vector<uint8_t> &data = networkMessage.data;
imemstream stream(reinterpret_cast<const char*>(data.data()), data.size());
processData(stream);

那么C ++確實有一個類 - istrstream ,你可以像這樣使用它:

    vector<uint8_t> data = ...;

    // need some way to create istream from data
    std::istrstream stream(reinterpret_cast<const char*>(data.data()), data.size());

    processData(stream);

據我所知,這不會復制數據,與其他答案不同。 但是它在C ++ 98中也被棄用了, 因為很難知道誰負責釋放緩沖區 ,所以你可能想編寫自己的等價物。

您可以通過將數據分配給std::string並使用綁定到它的std::istringstream (將unsigned char留給signed char轉換問題)來完成此操作:

std::string s((char*)networkMessage.data(),networkMessage.size());
std::istringstream iss(s);

std::istream& stream = iss;
         // ^ Note the reference here.

processData(stream);
stream.close();

這將適用於任何類型的矢量,而不僅僅是uint8_t

STD

template <class T>
auto make_istringstream_std_1(const std::vector<T>& v) -> std::istringstream
{
    using namespace std::string_literals;
    std::string str;

    for (auto& e : v)
    {
        str += std::to_string(e) + " "s;
    }
    // the trailing space is not an issue

    return std::istringstream{str};
}

標准算法

template <class T>
auto make_istringstream_std_2(const std::vector<T>& v) -> std::istringstream
{
    std::stringstream ss;
    std::copy(v.begin(), v.end(), std::ostream_iterator<int>(ss, " "));
    // the trailing space is not an issue

    return std::istringstream{ss.str()};
}

促進

template <class T>
auto make_istringstream_boost(const std::vector<T>& v) -> std::istringstream
{
    using boost::adaptors::transformed;
    using boost::algorithm::join;

    return std::istringstream{
        join(v | transformed([](int a) { return std::to_string(a); }), " ")};
}

歸因:

如何將vector <int>轉換為字符串?

boost :: algorithm :: join的一個很好的例子

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM