У меня очень большой (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 берет входной тип потока, который огромен (миллиарды миллиардов).
Изменение линии
in.seekg(index*length*sizeof(float), in.beg);
в
in.seekg((streamoff)index*length*sizeof(float), in.beg);
решил проблему.
int
для смещений, тогда какseekg
ожидаетoff_type
илиpos_type
которые, скорее всего, не являются псевдонимамиint
(но, скорее всего,std::size_t
который, вероятно, является 64-битным целочисленным типом). На всех основных современных платформах, даже на 64-битных платформах,int
по-прежнему является 32-битным типом, что недостаточно для такого большого числа.index*length*sizeof(float)
переполнен.