您的位置:首页 > 其它

MFC文件操作之CArchive

2012-03-16 08:44 288 查看
 

C++对于文件的操作的方式有很多种,大体分为4类。第一类是c函数,第二类是运用c++的fstream类对文件进行操作,第三类是运用Win
4000
dows API函数进行文件操作,第四类是运用MFC的类CFile对文件进行操作。

今天主要是想说一下运用CArchive,CFile类进行文件的操作。个人觉得这种方法比较简便常用,但有利必有弊,相对于c函数和c++的fstream,似乎灵活性要差一些,而且需要依赖于MFC类库。

CArchive允许以一个永久二进制(通常为磁盘存储)的形式保存一个对象的复杂网络,它可以在对象被删除时,还能永久保存。可以从永久存储中装载对象,在内存中重新构造它们。使得数据永久保留的过程就叫作“串行化”。

代码:

对于文件的写操作:分别写入一个int,char,float,CString类型的数据到”1.txt”文件中。

void CFileOperate::FileWrite()

{

CFile file("1.txt",CFile::modeCreate|CFile::modeWrite);

CArchive ar(&file,CArchive::store);

int i=4;

char ch='a';

float f=1.3f;

CString str("http:://www.flyhorse.cn");

//保存数据

ar<<I<<CH<<F<<STR; 运用<<直接向文件中写入数据

ar.Close();

file.Close();

AfxMessageBox("数据保存成功!");

}

对于文件的读操作:从”1.txt”文件中读出上边写的int,char,float,CString类型的数据。

void CFileOperate::FileRead()

{

CFile file("1.txt",CFile::modeRead);

CArchive ar(&file,CArchive::load);

int i;

char ch;

float f;

CString str;

CString strResult;

//读取数据

ar>>i>>ch>>f>>str; //这里需要注意的是读出数据的顺序要跟写入数据的顺序相同

ar.Close();

file.Close();

strResult.Format("%d,%c,%f,%s",i,ch,f,str);

AfxMessageBox(strResult);

}

是不是很方便,可以对任意类型的数据随意的读写,而且数据都是以二进制的形式存储到文件中的,可以用UE打开1.txt查看文件的二进制格式。

而运用CFile和CArchive更多的是对象的串行化,将类的对象以二进制的形式串行化到文件中,使得类的对象得以永久保存。

但是想方便的进行对象的存储,总是需要点条件的,那就是这个对象必须是支持串行化的,也就是说不是所有的对象都可以用CArchive串行化到文件中,是不是很受打击?就好像想给人一块美味可口的蛋糕,但是前提你得先围着操场跑几圈一样.

幸运的是创建一个支持串行化的类并不复杂,只要按照以下5步进行创建,就大功告成啦!

1. 从CObject派生类或者是从CObject派生的某个类派生。

2. 重写Serialize成员函数。

3. 使用DECLARE_SERIAL宏(在类中声明)。该宏形式如下:

DECLARE_SERIAL(class_name) //class_name串行化类的类名

4. 定义一个不带参数的构造函数。

5. 在类的实现文件中使用IMPLEMENT_SERIAL宏。该宏形式如下:

IMPLEMENT_SERIAL(class_name,base_class_name, wSchema) // wSchema版本号

通过上边5个步骤就可以创建一个支持串行化的类了。

例如我想创建一个存储用户信息的支持串行化的CUserInf类,代码如下:

###############CUserInf.h##################################

class CUserInf:public CObject

{

DECLARE_SERIAL(CUserInf) // DECLARE_SERIAL宏

public:

CUserInf(); //不带参数的构造函数

CUserInf(CString username,CString passwd,CString question,CString answer);

virtual ~CUserInf();

void Serialize(CArchive& ar); //重写Serialize函数

void GetUserInf(CString &userinf);

private:

CString _username; //用户名

CString _passwd; //密码

CString _question; //密保问题

CString _answer; //答案

};

############################CUserInf.cpp#########################

IMPLEMENT_SERIAL(CUserInf,CObject,1) // IMPLEMENT_SERIAL宏

CUserInf::CUserInf() //不带参数的构造函数

{

}

CUserInf::CUserInf(CString username,CString passwd,CString question,CString answer)

{

_username=username;

_passwd=passwd;

_question=question;

_answer=answer;

}

CUserInf::~CUserInf()

{

}

void CUserInf::Serialize(CArchive& ar) //重写的Serialize函数

{

if(ar.IsStoring()) //向文件中存储对象

{

ar< _username< _passwd< _question< _answer;

}

Else //从文件中取出对象

{

ar>>this->_username>>this->_passwd>>this->_question>>this->_answer;

}

}

void CUserInf::GetUserInf(CString &userinf)

{

userinf=_username+" "+_passwd+" "+_question+" "+_answer;

}

以上就是一个支持串行化的类的创建,只需5步,就大功告成!

下边我们来看看如何将我们的类串行化到文件中。

向文件中写入对象:

void CCArchivetestDlg::UserInfWrite()

{

// 创建两个对象

CUserInf user1("悟空","123","我的名字?","孙行者");

CUserInf user2("八戒","456","我的名字?","猪悟能");

//创建或打开userinf.archive文件,进行写操作

CFile file("userinf.archive",CFile::modeCreate|CFile::modeWrite);

CArchive iar(&file,CArchive::store);

//向文件中写入对象

iar<<&user1<<&user2;

//ar.WriteObject(&user1);

//ar.WriteObject(&user2);

iar.Close();

file.Close();

MessageBox("用户信息写入成功!");

}

从文件中读取对象:

void CCArchivetestDlg::UserInfRead()

{

//定义两个对象指针

CUserInf *puser1=NULL;

CUserInf *puser2=NULL;

CFile file("userinf.archive",CFile::modeRead);

CArchive oar(&file,CArchive::load);

//从文件读取数据

oar>>puser1>>puser2;

oar.Close();

file.Close();

CString user1;

CString user2;

puser1->GetUserInf(user1);

puser2->GetUserInf(user2);

MessageBox(user1+user2);

}

以上为对象的串行化和反串行化过程,希望对读者有帮助!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mfc user file 存储 float class