【发布时间】:2019-05-14 19:45:42
【问题描述】:
我正在编写一段代码以使用 C++ IOStreams 读取跨越多个文件的数 GB 数据,出于多种设计原因,我选择了 C++ IOStreams,而我不会让您感到厌烦。由于数据是由运行我的代码的同一台机器上的单独程序生成的,因此我相信在大多数情况下可以忽略与字节序相关的问题。
文件的结构相当复杂。例如,有一个标头描述了特定二进制配置的记录数。在文件的后面,我必须使代码有条件地读取该行数。这种模式以一种复杂但有据可查的方式重复出现。
我的问题与如何有效地执行此操作有关 - 我确定我的过程将受到 IO 限制,所以我的直觉是,而不是读取小块中的数据,例如以下方法
std::vector<int> buffer;
buffer.reserve(500);
file.read( (char*)&buffer[0], 500 * sizeof(int));
我应该一次完全读取一个文件并尝试在内存中处理它。所以我的相关问题:
- 鉴于这似乎意味着读取 char* 或 std::vector 数组,您最好如何将此数组转换为正确表示文件结构所需的数据格式?
- 我的假设不正确吗?
我知道显而易见的答案是先尝试,然后再进行分析,我当然会进行分析。但这个问题更多的是关于如何在一开始就选择正确的方法——一种“选择正确的算法”优化,而不是我以后发现瓶颈后可以设想的那种优化!
我会对提供的答案感兴趣 - 我往往只能找到相对简单的二进制文件的答案,而上述方法适用于这些文件。我的问题是,大部分二进制数据是根据文件头中的数字有条件地构建的(即使头是这样格式化的!)所以我需要能够更仔细地处理文件。
提前致谢。
编辑: 一些关于内存映射的 cmets - 看起来不错,但不知道该怎么做,我读过的所有内容都告诉我它不可移植。我有兴趣尝试 mmap,但也有兴趣更便携的解决方案(如果有的话!)
【问题讨论】:
-
要考虑的一个选项是将整个文件映射到内存中,然后使用字符或小块。
-
非常有趣.. :) 您能否详细说明“二进制数据的结构取决于文件标题中的数字”,例如是否像标题描述该文件中的整数一样简单?
-
@thekashyap:不完全是。该文件描述了某些对象,并将使用不同结构的二进制记录来这样做。作为一个简化的例子,它可能表明有 10 只猫和 5 个猫瓣。 “cat”记录的结构可能是(int numWhiskers,int numLives,double tailLength),而“catflap”可能是(double height, double width, int numberOfOpenings)。然后标题告诉我当我到达文件的那个位时要读取的每条记录的数量。我希望这能让它更清楚!
-
您是否总是需要按相同顺序排列对象?为什么不直接读取大块文件并将它们传递给解析器?
-
@DavidSchwartz:不知道你的意思——文件以特定的顺序向我展示对象,所以我就是这样阅读它们的。认为我误解了你在说什么:)
标签: c++ performance binary binaryfiles