[英]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
作為其底層緩沖區,然后您可以構造一個使用該內存streambuf
的std::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
:
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); }), " ")};
}
歸因:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.