2011-06-27 7 views
6

próbuję odczytać plik binarny do tablicy strukturyodczytać cały plik binarny do tablicy w pojedynczy połączeń C++

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; 
}; 

poniższy kod prac, ale robi to jeden element na raz, przez naciśnięcie każdego nowym elementem na tablicy

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(); 
    } 
} 

Chcę ją przyspieszyć czytając całą tablicę na raz, co moim zdaniem powinno wyglądać jak na poniższym

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; 
} 

Ale odczyt powoduje błąd seg, jak to naprawić?

+3

Przewiduję, że gdy już to zrobisz, będziesz zaskoczony tym, jak niewiele poprawia twoją wydajność. – Nemo

+1

Zrób sobie przysługę i użyj 'std :: string' zamiast' strcat'. –

Odpowiedz

3

Tak jest źle:

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

Masz zamiar odczytać dane do wektora, należy zmienić jego rozmiar, a nie tylko rezerwy, tak:

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

To też jest źle:

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

Nie zapisujesz tam danych wektorowych, nadpisujesz samą strukturę, wraz z ho wie, co jeszcze. Powinno być tak:

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

Tak jak powiedział Nemo, jest to mało prawdopodobne, aby poprawić wydajność.

+0

Brakujące i włączone funkcje [0]? – Pablo

+0

Dobrze, to inicjalizuje całą (większą niż cache) tablicę, a następnie wypełnia ją. Więc nawet jeśli dysk nie był wąskim gardłem, nie byłoby to szybsze niż oryginalny kod. "rezerwa" plus "push_back" jest zwykle szybsza ... Jeśli nie czytasz z dysku o milionach wolniejszych pamięciach. – Nemo

0

Twój typ features to std :: vector, a ty go dopasowujesz do char. Wektor typu nie jest tablicą.

0

myślę chcesz

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

Należy również upewnić się, że size jest wielokrotnością sizeof(FeaturePoint). W przeciwnym razie przeczytasz za dużo.