c++ 二进制文件读写
参考博客:
C++二进制文件的读取和写入(精华版) (先看且全看)
C/C++读写文本文件、二进制文件 (我只看了 五)
学习此内容的目的是我需要将原本存储内容的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; }
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(); }
读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; }