在C++中,将整个二进制文件一次性读入数组

6
我正在尝试将一个二进制文件读入到结构数组中。
struct FeaturePoint
{  
  FeaturePoint (const int & _cluster_id, 
            const float _x, 
            const float _y, 
            const float _a, 
            const float _b
            ) : cluster_id (_cluster_id), x(_x), y(_y), a(_a), b(_b) {}
  FeaturePoint (){}
  int cluster_id; 
  float x;
  float y;
  float a;
  float b;
};

下面的代码可以运行,但是一次只能处理一个元素,通过将每个新元素推入数组中。
void LoadImageFeaturesFromBinaryFile(const char * FileName, std::vector<FeaturePoint>& features )
{
  char strInputPath[200];
  strcpy (strInputPath,"/mnt/imagesearch/tests/");
  strcat (strInputPath,FileName);
  strcat (strInputPath,".bin");
  features.clear();
  ifstream::pos_type size;
  ifstream file (strInputPath, ios::in|ios::binary|ios::ate);
  if (file.is_open())
  {
    size = file.tellg();
    cout<< "this file size is : "<<size<<" for "<<strInputPath<<" " <<sizeof( FeaturePoint )<<endl;
    file.seekg (0, ios::beg);
    while (!file.eof())
    {
      try
      { 
        FeaturePoint fp;
        file.read( reinterpret_cast<char*>(&fp), sizeof( FeaturePoint ) );  
        features.push_back(fp); 

      }
      catch (int e)
      { cout << "An exception occurred. Exception Nr. " << e << endl; }
    }

    sort (features.begin(), features.begin()+features.size(),CompareClusterIndexes);  
    file.close();
  }
}

我希望通过一次性读取整个数组来加快速度,我认为应该像下面这样:

    void LoadImageFeaturesFromBinaryFile(const char * FileName, std::vector<FeaturePoint>& features )
{
  char strInputPath[200];
  strcpy (strInputPath,"/mnt/imagesearch/tests/");
  strcat (strInputPath,FileName);
  strcat (strInputPath,".bin");
  features.clear();
  ifstream::pos_type size;
  ifstream file (strInputPath, ios::in|ios::binary|ios::ate);
  if (file.is_open())
  {
    size = file.tellg();
    file.seekg (0, ios::beg);
    features.reserve( size/sizeof( FeaturePoint ));
    try
    { 
      file.read( reinterpret_cast<char*>(&features),  size );  
    }
    catch (int e)
    { cout << "An exception occurred. Exception Nr. " << e << endl; }

    sort (features.begin(), features.begin()+features.size(),CompareClusterIndexes);  
    file.close();
  }
  else cout << strInputPath<< " Unable to open file for Binary read"<<endl;
}

但读取数据导致了分段错误,我该怎么修复它?


3
我预测一旦你达成这个目标,你会惊讶地发现它对你的表现改善很微小。 - Nemo
1
请自己一个忙,使用std::string代替strcat - Fred Foo
3个回答

3

这是错误的:

features.reserve( size/sizeof( FeaturePoint ));

您即将读取数据到向量中,您应该调整其大小,而不仅仅是保留空间,像这样:

features.resize( size/sizeof( FeaturePoint ));

这也是错误的:
file.read( reinterpret_cast<char*>(&features),  size );

在那里,你不是在覆盖向量的数据,而是在覆盖结构本身以及其他可能的内容。应该是这样的:

file.read( reinterpret_cast<char*>(&features[0]),  size );

不过,正如Nemo所说,这不太可能提高您的性能。


这将初始化整个(大于缓存的)数组,然后填充它。因此,即使磁盘不是瓶颈,这也不会比原始代码快。 "reserve"加上"push_back"通常更快...如果您没有从比内存慢一百万倍的磁盘中读取数据的话。 - Nemo

0

我想你需要的是

file.read( reinterpret_cast<char*>(&features[0]),  size );

您还需要确保sizesizeof(FeaturePoint)的倍数。否则,您将会读取稍微多一点。


0

您的features类型为std::vector,而您将其转换为char。vector类型不是数组。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接