序列化是從固定存儲介質中讀和寫一個對象的過程,例如磁盤文件。序列化一個對象需要三個要素:
Ø 一個描述數據文件的CFile對象
Ø 一個提供序列化上下文的Carchive對象
Ø 一個可以被序列化的對象
第一步:打開數據文件
用適當的存取方式打開用於保存序列化信息的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;
}
第二步:和存檔掛鉤
下一步,將一個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;
}
第三步:序列化對象
最後,我們調用Serialize()函數序列化對象。Serialize()函數是我們自己構造的函數,與MFC的CObject::Serialize()函數沒有任何關系。因此你也無需將對象從CObject類繼承。我們的Serialize()方法需要傳入一個CArchive對象指針,並返回一個表示狀態的整數。
int CFoo::serialize
(CArchive* pArchive)
{
int nStatus = SUCCESS;
// Serialize the object ...
...
return (nStatus);
}
我們在一分鐘內了解了實際的序列化過程。現在,讓我們認識一下一對要點:
1. 從固定存儲中讀取以及向固定存儲中寫入數據都是使用Cfoo::Serialize()函數。
2. 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);
}
第四步:清除
當我們完成序列化以後,我們應該關閉存檔和數據文件來清除。
pArchive->Close();
delete pArchive;
pFile->Close();
delete pFile();