2014-12-29 62 views
0

從C或C++,我想讀取儘可能快的二進制格式的雙份文件。Cpp讀取雙倍快速小型二進制文件

文件很小,通常在100KB左右(200 KB上)。我希望能夠:

  • 閱讀雙打文件。
  • 轉換/將它們存儲在雙精度矢量中
  • 遍歷矢量。

然後在2毫秒內完成。如果可能,在這個系統上。目前它大約在4-6毫秒。

線程幫助,但沒有解決的問題:

Link 1

Link 2 - >這甚至沒有編譯。

Link 3 - >這對雙打沒有效果。

Link 4 - >這樣做。

這裏是我的文件分析器:

閱讀「C」 樣式:

void OfflineAnalyser::readNParseData(const char* filePath, vector<double> *&data){ 

    // Temporary Variables 
    FILE* pFile; 
    long fileSize; 
    double *fileBuffer; 
    size_t sizeOfBuffer; 
    size_t result; 

    // Open File 
    pFile = fopen(filePath, "rb"); 

    if (pFile == NULL){ 
     cout << "File: " << filePath << " does not exist" << endl; 
    } 

    // Check whether the parameter is already full 
    if (!data){ 
     // Reset the output 
     data->clear(); 
     data = 0; 
    } 

    // Obtain file size: 
    fseek(pFile, 0, SEEK_END); 
    fileSize = ftell(pFile); 
    rewind(pFile); 

    // allocate memory to contain the whole file: 
    fileBuffer = (double*)malloc(fileSize); 

    if (fileBuffer == NULL) { fputs("Memory error", stderr); exit(2); } 

    // copy the file into the buffer: 
    result = fread(fileBuffer, 1, fileSize, pFile); 
    if (result != fileSize) { 
     fputs("Reading error", stderr); 
     system("pause"); 
     exit(3); 
    } 

    // the whole file is now loaded in the memory buffer. 
    sizeOfBuffer = result/sizeof(double); 

    // Now convert the double array into vector 
    data = new vector<double>(fileBuffer, fileBuffer + sizeOfBuffer); 

    free(fileBuffer); 
    // terminate 
    fclose(pFile); 
} 

方法2:C++風格

void OfflineAnalyser::readNParseData2(const char* filePath, vector<double> *&data){ 

    ifstream ifs(filePath, ios::in | ios::binary); 

    // If this is a valid file 
    if (ifs) { 
     // Temporary Variables 
     std::streampos fileSize; 
     double *fileBuffer; 
     size_t sizeOfBuffer; 

     // Check whether the parameter is already full 
     if (!data){ 
      // Reset the output 
      data->clear(); 
      data = 0; 
     } 

     // Get the size of the file 
     ifs.seekg(0, std::ios::end); 
     fileSize = ifs.tellg(); 
     ifs.seekg(0, std::ios::beg); 

     sizeOfBuffer = fileSize/sizeof(double); 
     fileBuffer = new double[sizeOfBuffer]; 

     ifs.read(reinterpret_cast<char*>(fileBuffer), fileSize); 

     // Now convert the double array into vector 
     data = new vector<double>(fileBuffer, fileBuffer + sizeOfBuffer); 

     free(fileBuffer); 
    } 
} 

任何建議到這個代碼非常感謝。隨意輸入你自己的代碼。 如果我能看到雙打或istream_iterator解決方案的std :: copy,我會很高興。

在此先感謝。

回答

-1

由於vector會按順序存儲元素,因此將文件緩衝區讀取到矢量的數據緩衝區會更有效率。

void readNParseData(const char* filePath, vector<double>& data){ 

    // Temporary Variables 
    FILE* pFile; 
    long fileSize; 
    size_t result; 

    // Open File 
    pFile = fopen(filePath, "rb"); 

    if (pFile == NULL){ 
     cout << "File: " << filePath << " does not exist" << endl; 
    } 

    // Check whether the parameter is already full 
    if (!data.empty()){ 
     data.clear(); 
    } 

    // Obtain file size: 
    fseek(pFile, 0, SEEK_END); 
    fileSize = ftell(pFile); 
    rewind(pFile); 

    data.resize(fileSize/8); 
    if(fread(&(data[0]), 1, fileSize, pFile) != fileSize) 
    { 
     cout << "read error" << endl; 
    } 

    fclose(pFile); 
} 

我已經測試你的代碼和我solution.Your代碼需要大約21ms時,文件大小爲20,000KB,和我的解決方案需要大約16毫秒。

此外,代碼中存在一個錯誤。 if(!data)更應該是if(data)

+1

沒有錯誤。我上面給出的代碼工作得非常好(如果數據爲空(0),!數據將是1,它將進入if)。事實上,我已經試過你的代碼與一個指針不得不修復以下兩行,讓人感受:if(!data-> empty()){]給出exp和data-> resize(fileSize/8);也給出例外。修正了它們,但fread也會產生異常。所以我嘗試了你的代碼版本(正是你上面給出的代碼)。讀取的double值不正確。我正在從Hex編輯器和我自己的代碼中檢查兩者。返回的值不正確。可能你可以修改你的代碼? – JohnJohn

+0

哦,我的道歉,我調用函數之前,我調用函數「矢量 *數據= 0」,然後我調用函數,我現在正在做一個if(data!= 0)檢查。感謝您指出了這一點。 – JohnJohn