【发布时间】:2011-05-09 17:05:53
【问题描述】:
我最近一直在使用 C/C++ 加载很多二进制文件,但我对它的不优雅感到困扰。要么我得到很多看起来像这样的代码(我已经继续前进了):
uint32_t type, k;
uint32_t *variable;
FILE *f;
if (!fread(&type, 4, 1, f))
goto boundsError;
if (!fread(&k, 4, 1, f))
goto boundsError;
variable = malloc(4 * k);
if (!fread(variable, 4 * k, 1, f))
goto boundsError;
或者,我定义了一个本地的、打包的结构,以便我可以更轻松地读取固定大小的块。然而,在我看来,对于这样一个简单的问题——即将指定的文件读入内存——可以更有效地以更易读的方式完成。有没有人有任何提示/技巧等?我想澄清一下,我不是在寻找图书馆或其他东西来处理这个问题;如果我正在设计自己的文件并且不得不大量更改文件规范,我可能会受到诱惑,但现在我只是在寻找风格上的答案。
另外,你们中的一些人可能会建议mmap——我喜欢 mmap!我经常使用它,但它的问题是它会导致用于处理未对齐数据类型的讨厌的代码,而在使用 stdio 时这并不真正存在。最后,我将编写类似 stdio 的包装函数来从内存中读取。
谢谢!
编辑:我还应该澄清我不能更改文件格式——我必须阅读一个二进制文件;我无法请求其他格式的数据。
【问题讨论】:
-
mmap()!与union一起处理未对齐的数据访问。 -
我希望我能做到,但性能损失值得吗?这就是避免它的初衷。我的意思是,说实话,我可能会在不知不觉中在我的
FILE的缓冲区中进行未对齐的内存访问。 -
您是否实际测量过性能影响?非对齐访问在 x86 上相对便宜。
-
未对齐读取的问题与其说是对性能的影响(如果有的话)(几个周期的惩罚通常在这里并不重要,因为 IO 比计算贵得多),而是它将导致程序在一些根本不支持未对齐读取的 RISC 平台上崩溃。但是话又说回来,由于字节序和
struct包装差异,通过fread阅读任何内容都会导致可移植性问题。 -
Elegant、I/O 和 C++:任选其一!