ищите, терпите неудачу на больших файлах

0

У меня очень большой (950GB) двоичный файл, в котором я храню 1 миллиард последовательностей точек с плавающей точкой.

Небольшим примером типа файла, который у меня есть с последовательностями длины 3, может быть:

-3.456 -2.981 1.244
2.453 1.234 0.11
3.45 13.452 1.245
-0.234 -1.983 -2.453

Теперь я хочу прочитать определенную последовательность (скажем, последовательность с индексом = 2, поэтому 3-я последовательность в моем файле), поэтому я использую следующий код:

#include <iostream>
#include <fstream>
#include <stdlib.h>

using namespace std;

int main (int argc, char** argv){

  if(argc < 4){
    cout << "usage: " << argv[0] << " <input_file> <length> <ts_index>" << endl;
    exit(EXIT_FAILURE);
  }

  ifstream in (argv[1], ios::binary);
  int length = atoi(argv[2]);
  int index = atoi(argv[3]);

  float* ts = new float [length];

  in.clear();
  **in.seekg(index*length*sizeof(float), in.beg);**
  if(in.bad())
    cout << "Errore\n";
  **// for(int i=0; i<index+1; i++){**                                                                                                                
  in.read(reinterpret_cast<char*> (ts), sizeof(float)*length);
  **// }**                                                                                                                                            
  for(int i=0; i<length; i++){
    cout << ts[i] << " ";
  }

  cout << endl;
  in.close();
  delete [] ts;
  return 0;
}

Проблема в том, что когда я использую seekg, это чтение терпит неудачу для некоторых индексов, и я получаю неправильный результат. Если я прочитаю файл последовательным образом (без использования seekg) и распечатаю нужную последовательность, я всегда получаю правильный результат.

Сначала я думал о переполнении в seekg (так как количество байтов может быть очень большим), но я видел, что seekg берет входной тип потока, который огромен (миллиарды миллиардов).

  • 0
    Основная проблема состоит в том, что вы используете int для смещений, тогда как seekg ожидает off_type или pos_type которые, скорее всего, не являются псевдонимами int (но, скорее всего, std::size_t который, вероятно, является 64-битным целочисленным типом). На всех основных современных платформах, даже на 64-битных платформах, int по-прежнему является 32-битным типом, что недостаточно для такого большого числа.
  • 0
    Ваши целые числа 32-битные? Возможно, целочисленный математический index*length*sizeof(float) переполнен.
Показать ещё 2 комментария
Теги:
binaryfiles

1 ответ

1
Лучший ответ

Изменение линии

in.seekg(index*length*sizeof(float), in.beg);

в

in.seekg((streamoff)index*length*sizeof(float), in.beg);

решил проблему.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню