1

我有一个二进制数据文件,其中包含 2d 和 3d 坐标,顺序如下:

uint32 numberOfUVvectors;
2Dvec uv[numberOfUVvectors];
uint32 numberOfPositionVectors;
3Dvec position[numberOfPositionVectors];
uint32 numberOfNormalVectors;
3Dvec normal[numberOfNormalVectors];

2Dvec 和 3Dvec 是分别由 2 个和 3 个浮点数组成的结构。

起初,我使用“通常”的方式读取所有这些值:

in.read(reinterpret_cast<char *>(&num2d), sizeof(uint32));
2Dvectors.reserve(num2d); // It's for an std::vector<2DVec> 2Dvectors();
for (int i = 0; i < num2d; i++){
    2Dvec 2Dvector;
    in.read(reinterpret_cast<char *>(&2Dvector), sizeof(2DVec));
    2Dvectors.push_back(2Dvector);
}

它工作得很好,但是速度很慢(一个文件中可能有超过 200k 的条目,并且有这么多的读取调用,硬盘访问成为一个瓶颈)。我决定一次将整个文件读入缓冲区:

in.seekg (0, in.end);
int length = in.tellg();
in.seekg (0, in.beg);

char * buffer = new char [length];

is.read (buffer,length);

现在读取速度更快了,但问题是:如何将该 char 缓冲区解析回整数和结构?

4

2 回答 2

2

要回答您的具体问题:

unsigned char * pbuffer = (unsigned char *)buffer;

uint32 num2d = *((uint32 *)pbuffer);
pbuffer += sizeof(uint32);
if(num2d)
{
    2Dvec * p2Dvec = (2Dvec *)pbuffer;
    2Dvectors.assign(p2Dvec, p2Dvec + num2d);
    pbuffer += (num2d * sizeof(2Dvec));
}

uint32 numpos = *((uint32 *)pbuffer);
pbuffer += sizeof(uint32);
if(numpos)
{
        3Dvec * p3Dvec = (3Dvec *)pbuffer;
    Pos3Dvectors.assign(p3Dvec, p3Dvec + numpos);
    pbuffer += (numpos * sizeof(3Dvec));
}

uint32 numnorm = *((uint32 *)pbuffer);
pbuffer += sizeof(uint32);
if(numnorm)
{
    3Dvec * p3Dvec = (3Dvec *)pbuffer;
    Normal3Dvectors.assign(p3Dvec, p3Dvec + numnorm);
    pbuffer += (numnorm * sizeof(3Dvec));
}
// do not forget to release the allocated buffer

一个更快的方法是:

in.read(reinterpret_cast<char *>(&num2d), sizeof(uint32));
if(num2d)
{
    2Dvectors.resize(num2d);
    2Dvec * p2Dvec = &2Dvectors[0];
    in.read(reinterpret_cast<char *>(&p2Dvec), num2d * sizeof(2Dvec));
}
//repeat for position & normal vectors
于 2013-05-22T17:17:01.877 回答
1

使用具有适当大小和起始值的 memcpy

或转换值(示例):

#include <iostream>

void copy_array(void *a, void const *b, std::size_t size, int amount)
{
    std::size_t bytes = size * amount;
    for (int i = 0; i < bytes; ++i)
        reinterpret_cast<char *>(a)[i] = static_cast<char const *>(b)[i];
}

int main()
{
    int a[10], b[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    copy_array(a, b, sizeof(b[0]), 10);

    for (int i = 0; i < 10; ++i)
        std::cout << a[i] << ' ';
}
于 2013-05-22T16:55:20.493 回答