C++ 如何从uint8\t向量创建istream?
我正在将通过网络获取数据的能力添加到过去只读取本地文件的代码中。我使用的网络库以C++ 如何从uint8\t向量创建istream?,c++,C++,我正在将通过网络获取数据的能力添加到过去只读取本地文件的代码中。我使用的网络库以向量的形式发送和接收数据。我希望能够在读取文件后重用处理数据的代码,但该代码需要std::istream,有没有办法让istream读取向量数据?这是相同的数据,所以我觉得应该有一种方法,但我还没有找到或想出如何做到这一点的代码 当前代码: std::ifstream stream("data.img", std::ios::in | std::ios::binary | std::ios::ate);
向量的形式发送和接收数据。我希望能够在读取文件后重用处理数据的代码,但该代码需要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();
vector data=networkMessage.data;
//需要一些从数据创建istream的方法吗
std::istream流=?
处理数据(流);
stream.close();
有没有办法做到这一点,或者我选错了树?您可以通过将数据分配给并使用绑定来实现这一点(撇开无符号字符
到有符号字符
的转换问题不谈):
std::basic_istream
从关联的std::basic_streambuf
派生类获取其数据。STL为文件I/O和字符串I/O提供此类类,但不为内存I/O或网络I/O提供此类类
您可以轻松编写(或找到第三方)基于内存的streambuf
类,该类使用std::vector
作为其底层缓冲区,然后您可以构造一个std::istream
使用该内存streambuf
。例如(使用来自的imemstream
类
):
std::vector&data=networkMessage.data;
imemstream流(reinterpret_cast(data.data()),data.size());
处理数据(流);
这将适用于任何类型的向量,而不仅仅是uint8\t
:
性病
模板
自动生成istringstream\u std\u 1(const std::vector&v)->std::istringstream
{
使用名称空间std::string_文本;
std::字符串str;
用于(自动和电气:v)
{
str+=std::to_字符串(e)+“s;
}
//尾随空格不是问题
返回std::istringstream{str};
}
std算法
模板
自动生成istringstream\u std\u 2(const std::vector&v)->std::istringstream
{
std::stringstream-ss;
std::copy(v.begin(),v.end(),std::ostream_迭代器(ss,“”);
//尾随空格不是问题
返回std::istringstream{ss.str()};
}
促进
模板
自动生成istringstream\u boost(const std::vector&v)->std::istringstream
{
使用boost::Adapters::transformed;
使用boost::算法::join;
返回std::istringstream{
join(v | transformed([](int a){return std::to_string(a);}),“”)};
}
归属:
< C++ >实际上C++有一个类,你可以这样使用:
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);
向量数据=。。。;
//需要一些从数据创建istream的方法吗
std::istrstream流(reinterpret_cast(data.data()),data.size());
处理数据(流);
据我所知,这并没有复制数据,不像其他答案。但是,它在C++98中也被弃用,因此您可能需要编写自己的等效程序
istream
是原始数据的参考。它不保存数据,只是一个访问者,方法是保留一些char*
指针作为数据内存地址的开始和结束
push_back()
,存储地址可能会更改,(复制内部向量)
istream
转换为常量向量
#包括
#包括
#包括
#包括
使用名称空间std;
模板
类vectorbuf:public std::streambuf{
公众:
向量BUF(标准::向量和v):_值(v){
char*bptr=(char*)_value.data();
char*eptr=(char*)(_value.data()+_value.size());
setg(bptr、bptr、eptr);
CoutInstancestd::istreamstream
源于std::istream
,您可以将iss
直接传递到processData()
,而无需声明中间变量:processData(iss);
此外,此解决方案的缺点是必须首先将std::vector
数据复制到std::string
,如processData()
无法直接读取std::vector
。@Remy我这样设计示例是为了清晰。它可能是为了清晰,但肯定不是为了效率/性能,尤其是对于大数据。是的,这会将数据复制到字符串中。不太可能是您想要的。这里有两个副本。如果使用boost,您可以直接使用由于涉及到所有的复制,这是非常低效的。这就是獾(尽管这种反对让我感到害怕,我个人使用的是Remy链接到的解决方案)可能的复制
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<uint8_t> data = ...;
// need some way to create istream from data
std::istrstream stream(reinterpret_cast<const char*>(data.data()), data.size());
processData(stream);