一次将文件读入矢量
Reading a file into a vector all at once
这是读取std::vector
的好主意吗,还是这里有一些问题:
using namespace std;
ifstream file("blah.dat", ios::binary);
vector<T> v(N);
file.read(static_cast<char*>(v.data()), N * sizeof(T));
vector
标准允许我这样做来填充矢量吗?为了简化起见,让我们假设T是一个普通的旧数据类型。
如果T
是可复制的,那么这里没有未定义的行为,POD当然是。保证vector<T>::data
返回指向vector<T>::size
T
s的连续数组的指针,并且保证普通可复制类型T
的对象表示是sizeof(T)
字节的连续序列(可能包括内部填充)。
如果存储在该空间中的字节不是有效的T
对象表示,则在访问它们时可能会得到未定义的行为。究竟哪个字节序列构成有效的CCD_ 10对象表示是一个灰色区域;至少,您应该能够将一个普通可复制类型的对象的底层字节可移植地写入文件,并成功地将它们读回同一类型对象的底层比特中。
为了偏执狂,我可能会说:
static_assert(std::is_trivially_copyable<T>(),
"NO NO NO - T MUST BE TRIVIALLY COPYABLE!");
在CCD_ 11之前用于将来的校对。
看起来您将受益于内存映射文件。Boost提供了两种实现,因此您不必直接使用mmap()
。
使用boost.iostreams:
#include <boost/iostreams/device/mapped_file.hpp>
boost::iostreams::mapped_file_source file("blah.dat");
std::size_t size = file.size() / sizeof(T);
const T * ptr = reinterpret_cast<const T*>(file.data());
for (std::size_t i=0; i<size; ++i)
std::cout << ptr[i] << std::endl;
您也可以使用boost.interprocess,但本质上相同的功能需要更多的代码。
主要优点是您不分配任何内存来访问文件,它将在访问数据时按需加载。数据本身将存在于缓存/缓冲的页面中,因此不会占用任何内存(如果系统需要其他内存,则会丢弃这些内存)。
你不应该这样做,事实上你应该做的(因为最初的C++)是这个
std::ifstream file("foo.txt");
file >> std::noskipws; // use this line so that whitespace won't be skipped
std::vector<char> buffer(std::istream_iterator<char>(file),
std::istream_iterator<char>());
你不应该按照自己的方式来做的原因是,对象存在于文件中是没有意义的(至少在C++中是这样)。文件只包含字符,然后由operator>>
格式化这些字符以创建对象。该标准允许编译器对对象做一些非常奇怪的事情(尤其是在启用RTTI时),这使得将对象"保存"到文件变得毫无用处。您最好只为它创建自己的序列化格式。
- 在C++中一次将矢量值写入多个文件
- 在一次迭代中从 txt 文件中读取多行
- 在头文件和 cpp 文件中使用一次 #pragma 时出现结构重定义错误
- 如何使用C++一次读取整个二进制文件
- C++,从文件读取到结构,然后读取到向量(结构被推入向量太多次,而不仅仅是一次)
- 如何遍历几个每小时一次的根(.root)文件,并将它们组合成更大的每日数据.root文件?
- 调用函数一次用于动态链接库,一次从可执行文件调用函数
- ifstream不会在下一次迭代中打开文件
- 汇总然后平均 txt 文件中每 10 行一次
- 如何从文本文件中一次读取一个字符
- 一次包含一个 #include 表达式的多个头文件?
- 传输文件一次又一次地发送相同的字节
- 无法一次从二进制文件中读取一个 int
- 使用 #pragma 一次,#ifndef 在同一文件中包含保护
- 如何从 int 一次写入一个字节的文件?C++
- 在循环工作时,首先将两个文件读为向量,但仅次于迭代一次
- 一次读取一个字符的文件,直到使用 read(2) 和 write(2) 换行符
- 一次又一次地重建以查看导入的 QML 文件更改
- C++一次从文本文件中获取每 2 个整数作为对
- 包含保护:为什么C++编译器不自动只包含每个头文件一次?