最近在写一个基于MFC对话框的小软件,软件中需要把一些用户的信息存放到一个数据文件中,需要时再取出来。想到以前学习MFC时有学过文档和串行化,于是就打算使用串行化来做。当然用其它方法也是可以的。这里只是为了学习!
CArchive 对象提供了一个类型安全缓冲机制,用于将可序列化对象写入 CFile 对象或从中读取可序列化对象。通常,CFile 对象表示磁盘文件;但是,它也可以是表示“剪贴板”的内存文件(CSharedFile 对象)。
想要详细学习请参见孙鑫的《VC++深入详解》
还可以参加这篇博客 点击打开链接 网上的一位网友做的笔记!
在对话框程序中想要使用串行化保存类的信息需要下面5个步骤:
a.让类从CObject派生;
b.覆盖Serialize()函数,在其中完成保存和读取功能;
c.在.h中加入 DECLARE_SERIAL(CClassName);
d.在.cpp中加入IMPLEMENT_SERIAL(CClassName, CObject, 1 );
e.定义一个不带参数的构造函数。
比如我的程序需要保存用户的信息,用户的信息包括用户名,用户密码等一些用户属性。我可以定义一个关于用户的类,在类中包含这些用户属性作为类的属性值。
头文件:
class CUserAccount : public CObject // a.让类从CObject派生; { DECLARE_SERIAL(CUserAccount) //c.在.h中加入 DECLARE_SERIAL(CClassName); CUserAccount(); //e.定义一个不带参数的构造函数。 virtual ~CUserAccount(); public: virtual void Serialize(CArchive&); //b.覆盖Serialize()函数,在其中完成保存和读取功能; CUserAccount (const CUserAccount &user); // copy-constructor CUserAccount &operator=(const CUserAccount &user); // =-operator CString m_strName; CString m_strPassword; };
#include "UserManager.h"
IMPLEMENT_SERIAL(CUserAccount, CObject, 1) // d.在.cpp中加入IMPLEMENT_SERIAL(CClassName, CObject, 1 );
CUserAccount::CUserAccount()
{
//m_bAccountDisabled = FALSE;
}
CUserAccount::~CUserAccount()
{
}
void CUserAccount::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// 'store' data
ar << m_strName;
ar << m_strPassword;
}
else
{
// 'load' data
ar >> m_strName;
ar >> m_strPassword;
}
}
/* Copy-constructor */
CUserAccount::CUserAccount(const CUserAccount &useracount)
{
m_strName = useracount.m_strName;
m_strPassword = useracount.m_strPassword;
}
/* = operator definition */
CUserAccount& CUserAccount::operator=(const CUserAccount &useracount)
{
if (&useracount != this)
{
m_strName = useracount.m_strName;
m_strPassword = useracount.m_strPassword;
}
return *this;
}
添加两个按钮,一个用于把数据写入文件,另一用于从文件中读取数据。在两个按钮的响应函数中添加的测试代码如下:
void CCArchiveTestDlg::OnBtnwrite() //写数据 { CUserAccount useraccount1; useraccount1.m_strName = _T("name1"); useraccount1.m_strPassword = "123456"; CUserAccount useraccount2; useraccount2.m_strName = _T("name2"); useraccount2.m_strPassword = "123456"; CUserAccount useraccount3; useraccount3.m_strName = _T("name3"); useraccount3.m_strPassword = "123456"; //CArray<CUserAccount, CUserAccount&> m_UserArray; 你可以把CArray看成一个数组。 m_UserArray.Add(useraccount1); m_UserArray.Add(useraccount2); m_UserArray.Add(useraccount3); CFile file; file.Open( "users.dat", CFile::modeWrite|CFile::modeCreate );//把数据写到users.dat这个文件中 CArchive ar(&file,CArchive::store); int nCount=3; //注意这个数据要先写到文件中,因为据时要先读到这个数据,不然不知道读几条数据! ar << nCount; for (int i=0; i < m_UserArray.GetSize(); i++) { m_UserArray[i].Serialize(ar); } ar.Flush(); ar.Close(); file.Close(); } void CCArchiveTestDlg::OnBtnread() //读数据 { CFile file; file.Open( "users.dat", CFile::modeRead ); CArchive ar(&file,CArchive::load); int nCount; ar >> nCount; for(int i=0; i<nCount; i++) { CUserAccount useraccount; // get user data useraccount.Serialize(ar); AfxMessageBox(useraccount.m_strName+_T(" ")+useraccount.m_strPassword); } ar.Close(); file.Close(); }
你可以按照上面的测试一下,这样再写MFC程序时很小的数据量你就不用再多此一举的去连什么数据库了,有时候真的不需要那个。很小的数据量保存的一个文件中就足够了!
下面是我写的测试程序的下载地址:http://download.csdn.net/detail/bcypxl/6782449
去工程目录下打开users.dat这个文件,你会发现里面的数据都是16进制的数据: