c++ 二進制文件讀寫


參考博客:

C++二進制文件的讀取和寫入(精華版) (先看且全看)

C/C++讀寫文本文件、二進制文件 (我只看了 五)

13.14C++對二進制文件的讀寫操作 (很好,可只看讀寫部分)

 

學習此內容的目的是我需要將原本存儲內容的csv文件轉移至dat二進制文件

在test5000.csv中保存了5000*128的float數

 

寫入binary.dat

#include <iostream>

#include <fstream>

#include <string>
#include <vector>
#include<algorithm>
using namespace std;
 
vector<vector<float> >a;  //��ά����洢�������
vector<float>b;

inline void file_to_string(vector<string> &record, const string& line, char delimiter);

inline float string_to_float(string str);

void read()
{
    vector<string> row;
    string line;
    string filename;
    ifstream in("test5000.csv");  
    if (in.fail())  { cout << "File not found" <<endl; return ; } 
    while(getline(in, line)  && in.good() )
    {
        file_to_string(row, line, ',');  //��line��ĵ�Ԫ�������ַ���ȡ��������,��Ϊ��Ԫ��ָ���
        for(int i=0, leng=row.size(); i<leng; i++){
            b.push_back(string_to_float(row[i]));
        }
        a.push_back(b);
        b.clear();
    }
    in.close();
    return ;
}


inline void file_to_string(vector<string> &record, const string& line, char delimiter)
{
    int linepos=0;
    char c;
    int linemax=line.length();
    string curstring;
    record.clear();
    while(linepos<linemax)
    {
        c = line[linepos];
        if(isdigit(c)||c=='.'){
            curstring+=c;
        }
        else if(c==delimiter&&curstring.size()){
            record.push_back(curstring);
            curstring="";
        }
        ++linepos;
    }
    if(curstring.size())
        record.push_back(curstring);
    return;
}
 

inline float string_to_float(string str){
    int i=0,len=str.length();
    float sum=0;
    while(i<len){
        if(str[i]=='.') break;
        sum=sum*10+str[i]-'0';
        ++i;
    }
    ++i;
    float t=1,d=1;
    while(i<len){
        d*=0.1;
        t=str[i]-'0';
        sum+=t*d;
        ++i;
    }
    return sum;
}


int main(){
    read();
    printf("total numbers of people: %d\n",a.size());
    vector<float> fea;
    ofstream outFile("binary.dat", ios::out | ios::binary);
    for (int i=0; i<a.size(); i++){
        fea = a[i];
        outFile.write((char*)&fea[0], 128*sizeof(float));
    }
    outFile.close();
    return 0;
}
View Code
ofstream outFile("binary.dat", ios::out | ios::binary);
for (int i=0; i<a.size(); i++){   fea = a[i];   outFile.write((char*)&fea[0], 128*sizeof(float)); } outFile.close();

a為vector<vector<float> >類型

fea為vector<float> 類型

 

讀binary.dat

#include <iostream>
#include <vector>
#include <fstream>
using namespace std;

int main(){
    ifstream inFile("binary.dat", ios::in | ios::binary);
    if(!inFile){
        cout<< "error" <<endl;
        return 0;
    }
    float fea[128];
    int n=0;
    while(inFile.read((char *)&fea[0], 128*sizeof(float))){
        //print dim1 of each img
        n++;
    }
    inFile.close();
    
    cout<<n<<endl;
    for(int i=0;i<128;i++)
        cout<<fea[i]<<" ";
    return 0;
}

可以看到確實讀出了這5000個向量,並存進了float數組

 

以上為測試內容,下面為我實際使用的情況

我在嘗試過程中結構體內使用了向量和string,結果報錯,我猜測這里的數據類型需要確定,盡量用數組,這樣可以准確的算出字節數。

class Face{
  public:
    float fea[128];
    char name[30];
};

讀取圖片保存至binary.dat二進制文件

//write binary.dat
void img2dat(){
    struct dirent *ptr, *ptr1;
    DIR *dir, *dir1;
    dir = opendir("../lfw_crop/");

    string file_path, temp;
    std::vector<Anchor> result_copy;
    int num = 0,count = 1;
    ofstream outFile("binary.dat", ios::out | ios::binary);
    Face face_temp[6000];

    // printf("lists of files:\n");
    while((ptr = readdir(dir)) != NULL){
        if(ptr->d_name[0] == '.')
            continue;

        //search subdirectory
        char sub_dir[50] = "../lfw_crop/";
        strcpy(face_temp[num].name, ptr->d_name);
        strcat(sub_dir, ptr->d_name);
        file_path = sub_dir;
        dir1 = opendir(sub_dir);

        while((ptr1 = readdir(dir1)) != NULL){
            if(ptr1->d_name[0] == '.')
                continue;

            temp = ptr1->d_name;
            file_path = file_path + "/" + temp;

            cv::Mat img = imread(file_path);
            count = 1;
            cout<<temp<<endl;
            Mat face = mt(img, result_copy, count);
            if (count){
                fea = extract_feature(face);
                for(int i=0;i<128;i++)
                    face_temp[num].fea[i] = fea[i];
                outFile.write((char*)&face_temp[num], sizeof(face_temp[num]));
                cout<<++num<<endl;
            }
            //just one img
            break;
        }
        closedir(dir1);
    }
    closedir(dir);
    outFile.close();
}
View Code

讀binary.dat並進行特征比對

if(count)
        {
            clock_t start_2, finish_2;
            start_2 = clock();
            vector<float> feature2 = extract_feature(face2);
            finish_2 = clock();

            cout << "mobilefacenet cost " << (float)(finish_2 - start_2) / CLOCKS_PER_SEC * 1000 << " ms" << endl;
            
            //2019.6.12
            int i=0, num=0;
            double curcal, max=0;
            string forecast_name;

            //2019.6.17
            // float fea[128];
            string name;
            clock_t start_3, finish_3;
            start_3 = clock();
            Face face_temp[6000];
            while(inFile.read((char *)&face_temp[num], sizeof(face_temp[num]))){
                curcal = calculSimilar(feature2, face_temp[num].fea);
                if(curcal > max){
                    max = curcal;
                    forecast_name = face_temp[num].name;
                } 
               }
            finish_3 = clock();

            cout << "search binary.dat cost & calculSimilar:" << (float)(finish_3 - start_3) / CLOCKS_PER_SEC * 1000 << " ms" << endl;
            cout << "max similarity is: "<< max << endl;
            cout << "forecast name is: "<< forecast_name <<endl <<endl;
        }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM