保存和读取文件
更新日期:2011-1-22
示例代码:demo.zip (请不要使用下载工具,否则可能出错)
测试环境:VC6.0+WinXP
━━━━━━━━━━━━━━━━━━━━━━━━
一、CMyFile实现了序列化保存和读取文件。你可以使用它保存和读取常用数据类型,如
1. int double short 等固定大小的变量,
2. 字符串变量,c风格字符串,stl 字符串string,MFC字符串CString
3. 保存stl的vector<T> 类型的变量
4. 保存结构体或结构体数组
5. 支持UNICODE
二、调用示例:
struct TEST { int a; int b; }; /**************************************************************************** 保存数据 ****************************************************************************/ bool write() { trace(_T("*****保存数据*****************")); //1.vector 变量 vector <TEST> button; for (int i=0;i<4;i++) { TEST temp={i,i+10}; button.push_back(temp); } //2.普通变量和结构体 TEST a={88,99}; int aa=34; double bb=11.352; //3.字符串变量 TCHAR c_str[100]=_T("this is a c style string"); __string stlstr=_T("this is a stl string"); CString mfcstr=_T("this is a mfc CString"); //4.保存用new创建的字符串 TCHAR* newstr; newstr=new TCHAR[100]; _tcsncpy(newstr,_T("the string using new"),99); //5.定义一个结构体指针,就一定要有相应的保存数量的变量count int count=10; TEST* pp=new TEST[count]; for (int i=0;i<count;i++) { pp[i].a=i; pp[i].b=i+100; } try { CMyFile file(_T("s.txt"),_T("wb")); file.WriteVector(button); file.WriteString(c_str); file.WriteString(stlstr); file.WriteString(mfcstr); file.WriteStruct(a); file.WriteStruct(aa); file.WriteStruct(bb); file.WriteString(newstr); delete[] newstr; newstr=NULL; file.WriteNewStruct(pp,count); delete[] pp; pp=NULL; trace(_T("CMyFile Write Successful")); return true; } catch(int ErrorCode) { trace(_T("CMyFile Write Failed"),ErrorCode); return false; } } /**************************************************************************** 读取数据 ****************************************************************************/ bool read() { trace(_T("*****读取数据*****************")); //1.vector 变量 vector <TEST> button; //2.普通变量和结构体 int aa=0; double bb=0; TEST a; //3.字符串变量 TCHAR c_str[100]={0}; __string stlstr; CString mfcstr; //4.保存用new创建的字符串 TCHAR* newstr; //5.定义一个结构体指针,就一定要有相应的保存数量的变量count TEST* pp; int count; try { CMyFile file(_T("s.txt"),_T("rb")); file.ReadVector(button); file.ReadString(c_str,sizeof(c_str)/sizeof(TCHAR)); file.ReadString(stlstr); file.ReadString(mfcstr); file.ReadStruct(a); file.ReadStruct(aa); file.ReadStruct(bb); for (UINT i=0;i<button.size();i++) trace(button[i].a,button[i].b); trace(c_str); trace(stlstr); trace(mfcstr); trace(a.a,a.b); trace(aa,bb); //读取用new创建的字符串 newstr=file.ReadNewString(); trace(newstr); delete[] newstr; newstr=NULL; count=file.ReadNewStruct(pp); trace(count); for (int i=0;i<count;i++) trace(pp[i].a,pp[i].b); delete[] pp; pp=NULL; trace(_T("CMyFile Read Successful")); return true; } catch(int ErrorCode) { trace(_T("CMyFile Read Failed"),ErrorCode); return false; } } void CDemoDlg::OnButton1() { write(); } void CDemoDlg::OnButton2() { read(); } |
三、CMyFile源代码(MyFile.h)
/**************************************************************************** 读取和保存文件 一、CMyFile实现了序列化保存和读取文件。你可以使用它保存和读取常用数据类型,如 1. int double short 等固定大小的变量, 2. 字符串变量,c风格字符串,stl 字符串string,MFC字符串CString 3. 保存stl的vector<T> 类型的变量 4. 保存结构体或结构体数组 5. 支持UNICODE 二、更新日期:2011-1-22 请浏览一下网址看是否有所更新: http://blog.csdn.net/jacky_qiu/archive/2010/12/24/6096722.aspx 三、调用示例: 通常你需要写两个函数write()和read()用于读取和保存。 里面还需要用try和catch来捕获保存和读取时可能出现的异常。 格式如下: //保存 bool write2() { int a=89; TCHAR c_str[100]=_T("this is a c style string"); try { CMyFile file(_T("s.txt"),_T("wb")); file.WriteStruct(a); file.WriteString(c_str); return true; } catch(int ErrorCode) { return false; } } //读取 bool read2() { int a; TCHAR c_str[100]={0}; try { CMyFile file(_T("s.txt"),_T("rb")); file.ReadStruct(a); file.ReadString(c_str,sizeof(c_str)/sizeof(TCHAR)); return true; } catch(int ErrorCode) { return false; } } ****************************************************************************/ #ifndef _MY_FILE_H_ #define _MY_FILE_H_ #include <vector> #include <string> //兼容ANSI和UNICODE #ifdef _UNICODE #define __fopen _wfopen #define __string wstring #else #define __fopen fopen #define __string string #endif class CMyFile { public: FILE* fp; CMyFile(const TCHAR* filename, const TCHAR* mode ) { fp=__fopen(filename,mode); if (fp==NULL) throw int(0); } ~CMyFile() { fclose(fp); } /**************************************************************************** 重新定位到文件开头 ****************************************************************************/ void fpReset() {rewind(fp);} /**************************************************************************** 保存vector ****************************************************************************/ template <class T> void WriteVector(std::vector<T>& vec) { UINT count=vec.size(); //保存个数 if (1!=fwrite(&count,sizeof(count),1,fp)) { fclose(fp); throw int(1); } if (count==0) return; //保存vector的所有元素 if (count!=fwrite(&vec[0],sizeof(T),count,fp)) { fclose(fp); throw int(2); } } /**************************************************************************** 读取vector ****************************************************************************/ template <class T> void ReadVector(std::vector<T>& vec) { UINT count=0; //一定要是UINT,否知有可能会出现负数 //读取个数 if (1!=fread(&count,sizeof(count),1,fp)) { fclose(fp); throw int(3); } //最多读取10万个数据 if (count>100000) { fclose(fp); throw int(4); } //设置Data的长度 vec.resize(count); if (count==0) return; if ( count!=fread(&vec[0],sizeof(T),count,fp) ) { fclose(fp); throw int(5); } } /**************************************************************************** 保存结构体,包括int double 之类的固定大小的变量 ****************************************************************************/ template <class T> void WriteStruct(T& Data) { if (1!=fwrite(&Data,sizeof(T),1,fp)) { fclose(fp); throw int(6); } } /**************************************************************************** 读取结构体,包括int double 之类的固定大小的变量 ****************************************************************************/ template <class T> void ReadStruct(T& Data) { if( 1!=fread(&Data,sizeof(T),1,fp)) { fclose(fp); throw int(7); } } /**************************************************************************** 保存string字符串 ****************************************************************************/ void WriteString(std::__string& str) { UINT count=str.size(); //保存个数 if (1!=fwrite(&count,sizeof(count),1,fp)) { fclose(fp); throw int(8); } if (count!=fwrite(str.c_str(),sizeof(TCHAR),count,fp)) { fclose(fp); throw int(9); } } /**************************************************************************** 读取字符串并放在一个string里 ****************************************************************************/ void ReadString(std::__string& str) { UINT count=0; //读取个数 if (1!=fread(&count,sizeof(count),1,fp)) { fclose(fp); throw int(10); } TCHAR* NewStr=new TCHAR[count+1]; if (count!=fread(NewStr,sizeof(TCHAR),count,fp)) { delete[] NewStr; throw int(11); } NewStr[count]=NULL; str=NewStr; delete[] NewStr; } #ifdef __AFXWIN_H__ /**************************************************************************** 保存CString字符串 ****************************************************************************/ void WriteString(CString& str) { UINT count=str.GetLength(); //保存个数 if (1!=fwrite(&count,sizeof(count),1,fp)) { fclose(fp); throw int(12); } if (count!=fwrite(str,sizeof(TCHAR),count,fp)) { fclose(fp); throw int(13); } } /**************************************************************************** 读取字符串并放在一个CString里 ****************************************************************************/ void ReadString(CString& str) { UINT count=0; //读取个数 if (1!=fread(&count,sizeof(count),1,fp)) { fclose(fp); throw int(14); } TCHAR* NewStr=new TCHAR[count+1]; if (count!=fread(NewStr,sizeof(TCHAR),count,fp)) { delete[] NewStr; throw int(15); } NewStr[count]=NULL; str=NewStr; delete[] NewStr; } #endif /**************************************************************************** 保存字符串 ****************************************************************************/ void WriteString(TCHAR* str) { UINT count=_tcslen(str); //保存个数 if (1!=fwrite(&count,sizeof(count),1,fp)) { fclose(fp); throw int(16); } if (count!=fwrite(str,sizeof(TCHAR),count,fp)) { fclose(fp); throw int(17); } } /**************************************************************************** 读取字符串 max包括了空字符,所以str的最大字符数为max-1 ****************************************************************************/ UINT ReadString(TCHAR* str,unsigned int max) { UINT count=0; //读取个数 if (1!=fread(&count,sizeof(count),1,fp)) { fclose(fp); throw int(18); } if (count>max-1) { fclose(fp); throw int(19); } if( count!=fread(str,sizeof(TCHAR),count,fp)) { fclose(fp); throw int(20); } str[count]=NULL; return count; } /**************************************************************************** 读取字符串(使用完后需手动删除,delete[] str) 当读取的是一个空字符串(WriteString时只写了一个count=0进入文件), 则ReadNewString会new一个字符NULL,所以我们可以安全引用此字符串指针。 ****************************************************************************/ TCHAR* ReadNewString() { UINT count=0; //读取个数 if (1!=fread(&count,sizeof(count),1,fp)) { fclose(fp); throw int(21); } if (count>100000) { fclose(fp); throw int(22); } TCHAR* str=new TCHAR[count+1]; if( count!=fread(str,sizeof(TCHAR),count,fp)) { delete[] str; fclose(fp); throw int(23); } str[count]=NULL;//length=100时,PasteText[length]就是第101个字符,也就是最后一个NULL return str; } /**************************************************************************** 保存结构体数组 即使pStruct为NULL,也可以调用此函数 ****************************************************************************/ template <class T> void WriteNewStruct(T* pStruct,UINT count) { //保存个数 if (1!=fwrite(&count,sizeof(count),1,fp)) { fclose(fp); throw int(24); } if (count!=fwrite(pStruct,sizeof(T),count,fp)) { fclose(fp); throw int(25); } } /**************************************************************************** 读取结构体数组 每次调用ReadNewStruct获得的结构体数组,在使用前必须判断是否为空 使用完需要delete[] pStruct ****************************************************************************/ template <class T> int ReadNewStruct(T* &pStruct) { UINT count=0; //读取个数 if (1!=fread(&count,sizeof(count),1,fp)) { fclose(fp); throw int(26); } if (count>100000) { fclose(fp); throw int(27); } if (count==0) { pStruct=NULL; return 0; } pStruct=new T[count]; if( count!=fread(pStruct,sizeof(T),count,fp)) { delete[] pStruct; fclose(fp); throw int(28); } return count; } }; #endif // #define _MY_FILE_H_ |