序列化入门 - 第 1 部分






4.64/5 (40投票s)
本教程描述了如何轻松地序列化一个简单的对象。
本文是关于序列化的 3 部分教程的第一部分。
序列化是将对象写入或从持久性存储介质(例如磁盘文件)读取的过程。 序列化一个对象需要 3 个要素
- 一个代表数据文件的
CFile
对象 - 一个提供序列化上下文的
CArchive
对象 - 被序列化的对象
第 1 步 - 打开数据文件
要将对象序列化到文件 "foo.dat",请使用适当的访问模式打开文件。 在本例中,该文件以独占读/写访问模式打开。
// Open file "foo.dat"
CFile* pFile = new CFile();
ASSERT (pFile != NULL);
if (!pFile->Open ("foo.dat", CFile::modeReadWrite | CFile::shareExclusive)) {
// Handle error
return;
}
第 2 步 - 连接归档文件
接下来,将一个 CArchive
对象连接到该文件。 归档文件提供了一种有效的通道,用于持久性存储。 您可以将数据序列化到归档文件和从归档文件中序列化数据,而不是直接读写文件。 归档文件需要知道您是使用它来读取还是写入数据。 在本例中,我们假设要写入数据。
// Create archive ...
bool bReading = false; // ... for writing
CArchive* pArchive = NULL;
try
{
pFile->SeekToBegin();
UINT uMode = (bReading ? CArchive::load : CArchive::store);
pArchive = new CArchive (pFile, uMode);
ASSERT (pArchive != NULL);
}
catch (CException* pException)
{
// Handle error
return;
}
第 3 步 - 序列化对象
最后,我们通过调用对象的 serialize()
方法来序列化对象。 serialize()
只是我们自己创建的一个方法。 它与 MFC 的 CObject::Serialize()
无关。 此外,您不必从 CObject
派生对象。 我们的 serialize()
方法接受一个指向 CArchive
的指针并返回一个整数状态。
int CFoo::serialize
(CArchive* pArchive)
{
int nStatus = SUCCESS;
// Serialize the object ...
...
return (nStatus);
}
稍后我们将开始实际的序列化过程。 与此同时,让我们认识到几个重要的点
- 使用相同的方法
CFoo::serialize()
来从/向持久性存储读取/写入对象。 CFoo::serialize()
不知道任何关于正在访问的数据文件的信息。
假设 CFoo
代表一个员工记录,其中包含几个数据成员。
class CFoo
{
// Construction/destruction
public:
CFoo::CFoo();
virtual CFoo::~CFoo();
// Methods
public:
int serialize (CArchive* pArchive);
// Data members
public:
CString m_strName; // employee name
int m_nId; // employee id
};
我们使用 CArchive
的流运算符 <<
和 >>
来从/向归档文件读取/写入数据成员。 CArchive
知道如何序列化简单的数据类型,如 int
、float
、DWORD
和对象(如 CString
)。 归档文件也知道它处于读取还是写入模式。 您可以通过调用 CArchive::IsStoring()
来查询其模式。 然后,CFoo
的序列化方法可以写成
int CFoo::serialize
(CArchive* pArchive)
{
int nStatus = SUCCESS;
// Serialize the object ...
ASSERT (pArchive != NULL);
try
{
if (pArchive->IsStoring()) {
// Write employee name and id
(*pArchive) << m_strName;
(*pArchive) << m_nId;
}
else {
// Read employee name and id
(*pArchive) >> m_strName;
(*pArchive) >> m_nId;
}
}
catch (CException* pException)
{
nStatus = ERROR;
}
return (nStatus);
}
第 4 步 - 清理
完成序列化后,您应该通过关闭归档文件和数据文件来清理。
pArchive->Close();
delete pArchive;
pFile->Close();
delete pFile();
结论
好了,这就是它 - 序列化(非常小)的概要。 在 第 2 部分 中,我们将了解如何优雅地处理读取无效数据存储以及支持对象的不同版本。 在 第 3 部分 中,我们将了解如何序列化复杂对象。