2009-06-19 152 views
2

我需要编写一个文件格式来将数据写入文件并且可以读取它。如何将二进制数据写入文件以便快速读取?

它应该能够以相当快的速度读取数据,这应该涉及将大块数据分块写入std::vector(因为它们的存储总是连续执行)。

但是,当写入文件时,我不知道如何强制对整数和其他类型的对齐和大小的约束。

应该怎么做?我在Q6600(x86)上的buntu linux上使用gcc。

只是作为一个例子:

struct Vertex 
{ 
    float point [3]; 
    float normal [3]; 
    float texcoord [2]; 
} 

稍后,数据被存储在一个std::vector<Vertex>。我曾考虑过使用__attribute__并对其进行打包/对齐,以便在不同的平台上更便携。

编辑: 我已经制定了一个规范,我打算使用它。数据的最大位是顶点和索引,所以这些数据将被读为大块,例如(较大规格的一部分): VertexGroup是一组共享特征的顶点。他们一次只能容纳一种材料,因此网格中应该包含许多材料。

<uint> thisid # Of this VertexGroup 
<string> name 
<uint> materialId # A material 
<uint> vertexCount 
for (vetexCount): 
    <3xfloat> point 
    <3xfloat> normal 
    <2xfloat> texcoord 
<uint> triangleCount 
for (triangleCount): 
    <3xuint> indices 

回答

2

这将取决于您的编译器和平台。据我所知,没有办法以完全交叉编译器和跨平台的方式执行此操作,而无需定义自己的大量宏。

但是,VC++和GCC(大二)都支持#pragma pack指令,这将允许您为结构定义对齐和打包。见http://msdn.microsoft.com/en-us/library/2e70t5y1.aspxhttp://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html

考虑到这一点,您可以使用#pragma pack来定义结构的对齐方式,然后使用fread()或类似的方法将字节从文件传输到内存。您可能需要在列表前添加列表长度,以便您可以一次为整个列表分配内存,然后使用单个I/O调用加载整个文件。

1

如果它只是POD(普通的旧数据),没有指针,那么你可以用fwrite和fread。这当然假设你完全会在同一个体系结构上读回与以前完全相同的格式。

考虑boost serialization

+0

增强序列化有多快?这可以节省很多麻烦,看看它的工作原理会很有趣。我想知道它是如何处理数组的,并且它的速度有多快(文件中有100万个顶点,因此不会将整个数据块移到内存中)。 – solinent 2009-06-19 17:06:12