2014-11-25 2 views
0

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

Небольшой пример типа файла у меня есть с последовательностями длины 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, поэтому третья последовательность в моем файле), поэтому я использую следующий код:

#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'] (http://en.cppreference.com/w/cpp/io/basic_istream/seekg) ожидает 'off_type' или' pos_type', которые скорее всего * не * псевдонимы 'int' (но скорее всего из' std :: size_t', который, вероятно, является 64-битным целым типом). На всех основных современных платформах, даже на 64-битных платформах, 'int' по-прежнему является 32-разрядным типом, который не подходит для таких больших чисел. –

+0

Являются ли ваши целые числа 32 бит? Возможно, переполняется целочисленная математическая 'index * length * sizeof (float)'. – drescherjm

+0

ваши комментарии оба правильные. добавление (подавление) проблемы устраняет проблему. Я думал, что приведение было автоматическим, так как seekg принимает тип потока – David

ответ

1

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

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

в

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

решить эту проблему.