从文件中读取碎片二进制数据并将其拆分为多个向量的最有效方法。 C ++

时间:2015-11-19 10:38:41

标签: c++ vector binaryfiles

我面临以下问题;我必须将文件中的二进制数据读入几个不同的向量。不幸的是,文件中的数据以不同方式对齐 因为我需要它在我的载体中。

示例:(V1.1 = Vector1值1,V2.4 =向量2值4)

文件布局: 已知矢量数,已知文件大小和数量 价值观是众所周知的。

V1.1 V2.1 V3.1 V4.1 V1.2 V2.2 V3.2 V4.2 V1.3 V2.3 V3.3 V4.3 ....

这些文件可以包含数百兆字节的数据,所以如果我只是 从中读取小块并将其拆分为我的向量(std :: copy) 这需要太多时间。

提前致谢, 尼科

以下某些"元代码": 由于单个值可以是不同类型,我首先计算 块大小,以及单个数据类型的长度,然后我直接读取 将单个值放入目标向量中,然后将其反向插入 一个不同的向量。 (最终的附加数据还需要做几个额外的 我真的不想经常打电话的事情。)

void readSimpleTypeInterleaved( rawDataBlock *rawDataBlock)  // this will be called multiple times for a single file
{
   unsigned int iChunkSize(0);
   std::vector< std::vector<BYTE> > aVectorOfData(rawDataBlock-    >numVectorDataCount);
   std::vector <unsigned int> vByteSizeVector(rawDataBlock->numVectorDataCount);

   fileStream().seekg( rawDataBlock->start, ios_base::beg);

   for(unsigned int i=0;i<rawDataBlock->numVectorDataCount;++i)
   {
      unsigned int iTypeSize = rawDataBlock->GetChannelDataSize(i);
      vByteSizeVector[i] = iTypeSize;
      iChunkSize += iTypeSize;
      aVectorOfData[i].reserve(  (rawDataBlock->byteLength / iTypeSize) / rawDataBlock->numChannels); // rough estimation (as block does sometimes contain different types
   }
   iChunkSize *= rawDataBlock->numOfElements;

   for (unsigned iCurrBytePosition=0; iCurrBytePosition < rawDataBlock-    >byteLength; iCurrBytePosition += chunkSize)
    {
        for (int iActualValue = 0; iActualValue < rawDataBlock->numOfElements; ++iActualValue)
        {
            for (unsigned int channel = 0; channel < rawDataBlock-    >numVectorDataCount; ++channel)
            {
                unsigned int iTypeSize(vByteSizeVector[channel]);
                unsigned int iVectorSize(aVectorOfChannelData[channel].size());
                aVectorOfChannelData[channel].resize(iVectorSize + iTypeSize);
                fileStream().readIntoVectorAt(aVectorOfChannelData[channel], iVectorSize, iTypeSize);
                // this is ifstream::read(reinterpret_cast<char*>(&aVectorOfChannelData[channel][iVectorSize]), iTypeSize);
            }
        }
    }

    for (unsigned int i = 0; i < rawDataBlock->numVectorDataCount; ++i)
    {
        pFile->AppendData(..., aVectorOfChannelData[i]);  // <- this does a resize + std::copy into another vector.
    }
}

1 个答案:

答案 0 :(得分:0)

此处的限制是从磁盘流式传输数据所需的时间,因此您需要专注于按顺序和尽可能快地读取数据。最大限度地减少任何寻求时间,让你和磁盘之间的缓存尽可能地工作,而不是在源文件中跳转。

在代码中设置映射,将传入的数据发送到数据结构中的正确位置,然后只读取磁盘中的数据并将其拆分到正确的位置。尝试多线程或以其他方式加速处理可能会使它变慢,因为瓶颈几乎肯定是磁盘。

您可以通过使用RAM磁盘存储数据来加快速度,但将数据复制到RAM磁盘只需要读取它就可以了,这样只有在重复读取时才有用。