使用MFC串行化保存程序数据

最近在写一个基于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.定义一个不带参数的构造函数。


比如我的程序需要保存用户的信息,用户的信息包括用户名,用户密码等一些用户属性。我可以定义一个关于用户的类,在类中包含这些用户属性作为类的属性值。

下面是我定义的类的头文件和实现文件,注意代码中的注释中按照上面串行化类的5个步骤进行了标注:

头文件:

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进制的数据:


你可能感兴趣的:(mfc,vc++,CArchive,串行化)