如何直接读入 std::vector?

问题描述 投票:0回答:1

我想将字节直接读入

std::vector
。 我想我想做这样的事情,其中
read()
是标准 Unix/Linux/Posix 系统调用,其中
n
是我想要读取的字节数:

std::vector<uint8_t> buf;
buf.reserve(n);
size_t r = read(fd, &buf[0], n);

这里的问题当然是,在执行

read
之后,我知道(在变量
r
中)有多少字节被读入向量,但向量本身不知道。 不知何故,我必须告诉向量现在有多大,之后
size()
将返回正确的大小。

但我不知道该怎么做。 有办法吗? 看来我需要一个

setsize
变异器,但我可以理解为什么它不存在。 有
resize()
,但我认为它会用默认值覆盖刚刚读取的数据。

我知道涉及

std::istreambuf_iterator<char>
的形式,如这个问题中所讨论的,但是(a)我没有这样的迭代器并且(b)我想在一个已经存在的向量上执行此操作(即不仅仅是在施工时间)。

c++ io stdvector read
1个回答
0
投票

您的方法存在一些问题。首先,即使矢量有容量,您也不能访问超出其实际大小的数据。其技术原因是未使用位置的数据尚未构建。但更具体地说,是因为这个使用规则是由标准描述的。

因为

buf
以零大小开始,因此访问
buf[0]
根本就是未定义的行为。如果您要使用
buf.at(0)
,则会引发异常。

此外,您使用了错误的数据类型来存储

read
的返回值。该函数返回
ssize_t
,而不是
size_t

要实现您想要的目标,您需要类似以下内容:

std::vector<uint8_t> buf(n);
ssize_t r = read(fd, buf.data(), n);
if (r > 0) {
    buf.resize(r);
} else {
    buf.clear();
}

这会构造一个具有

n
元素的新向量,这些元素最初是值初始化的。然后,它尝试将数据读入其中,并根据实际读取的项目数调整向量的大小。出错时,向量被清除

请注意,我使用

buf.data()
而不是
&buf[0]
来访问向量的内部数据。我认为这有更清晰的语义。

© www.soinside.com 2019 - 2024. All rights reserved.