CXArchive类:WTL中的序列化解决方案

WTL(Windows Template Library)是一个由微软开发人员创建的库,用于简化Windows应用程序的GUI创建过程。然而,WTL并不包含一些MFC中已有的高级特性,比如序列化支持。为了弥补这一缺陷,开发了CXArchive类,它是一个基于WTL的序列化解决方案,旨在简化WTL和非MFC应用程序中的序列化过程。

CXArchive类基于C++模板,允许开发者创建体积小且运行速度快的应用程序。CXArchive类使用CXFile类来读写文件数据,CXFile是一个对Windows文件API的封装类。CXArchive类实现了缓冲机制以提高性能。下面,将通过实现LONG类型的插入和提取操作符来理解CXArchive类的工作原理。

CXArchive类的声明

CXArchive类提供了多种模式,包括存储和加载,以及对缓冲区大小和缓冲区指针的管理。以下是CXArchive类的基本声明:

class CXArchive { public: enum Mode { store = 0, load = 1, bNoFlushOnDelete = 2 }; CXArchive(CXFile* pFile, UINT nMode, int nBufSize = 4096, void* lpBuf = NULL); ~CXArchive(); BOOL IsLoading() const; BOOL IsStoring() const; CXFile* GetFile() const; UINT Read(void* lpBuf, UINT nMax); void Write(const void* lpBuf, UINT nMax); void Flush(); void Close(); void Abort(); void WriteString(LPCTSTR lpsz); LPTSTR ReadString(LPTSTR lpsz, UINT nMax) throw(CXArchiveException); BOOL ReadString(CString& rString); // 插入操作符 CXArchive& operator<<(BYTE by); CXArchive& operator<<(WORD w); CXArchive& operator<<(LONG l); CXArchive& operator<<(DWORD dw); CXArchive& operator<<(float f); CXArchive& operator<<(double d); CXArchive& operator<<(LONGLONG dwdw); CXArchive& operator<<(ULONGLONG dwdw); CXArchive& operator<<(int i); CXArchive& operator<<(short w); CXArchive& operator<<(char ch); #ifdef _NATIVE_WCHAR_T_DEFINED CXArchive& operator<<(wchar_t ch); #endif CXArchive& operator<<(unsigned u); CXArchive& operator<<(bool b); // 提取操作符 CXArchive& operator>>(BYTE& by); CXArchive& operator>>(WORD& w); CXArchive& operator>>(DWORD& dw); CXArchive& operator>>(LONG& l); CXArchive& operator>>(float& f); CXArchive& operator>>(double& d); CXArchive& operator>>(LONGLONG& dwdw); CXArchive& operator>>(ULONGLONG& dwdw); CXArchive& operator>>(int& i); CXArchive& operator>>(short& w); CXArchive& operator>>(char& ch); #ifdef _NATIVE_WCHAR_T_DEFINED CXArchive& operator>>(wchar_t& ch); #endif CXArchive& operator>>(unsigned& u); CXArchive& operator>>(bool& b); protected: CXArchive(const CXArchive& arSrc) {} void operator=(const CXArchive& arSrc) {} void FillBuffer(UINT nBytesNeeded) throw(CXArchiveException); CXFile * m_pFile; string m_strFileName; BOOL m_bDirectBuffer; BOOL m_bBlocking; BOOL m_nMode; BOOL m_bUserBuf; int m_nBufSize; BYTE * m_lpBufCur; BYTE * m_lpBufMax; BYTE * m_lpBufStart; };

CXArchive类使用CXFile类指针来绑定文件,并实现缓冲以提高性能。插入操作符检查是否需要刷新内部CXArchive缓冲区,将LONG放入缓冲区并增加缓冲区指针。提取操作符检查是否需要从文件中获取更多数据到内部缓冲区,然后将缓冲区中的LONG数据放入LONG引用参数中。最后,增加缓冲区指针以准备下一次提取。

使用CXArchive类

使用CXArchive类的方式与使用CArchive类相同。在类中实现一个Serialize()函数,如下所示:

void CDriver::Serialize(CXArchive& ar) { if (ar.IsStoring()) { ar << m_byte; ar << m_word; } else { ar >> m_byte; ar >> m_word; } }

然后在代码中的某个地方添加以下行来序列化类:

string strFile = "demo.txt"; try { CXFile file1; file1.Open(strFile, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); CXArchive ar1(&file1, CXArchive::store); CDriver driver1; driver1.Serialize(ar1); ar1.Close(); } catch (CXException& Ex) { MessageBox(NULL, Ex.GetErrorDesc().c_str(), "Archive Demo", MB_OK); }

要反序列化它:

try { CXFile file2; file2.Open(strFile, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); CXArchive ar2(&file2, CXArchive::load); CDriver driver2; driver2.Serialize(ar2); ar2.Close(); } catch (CXException& Ex) { MessageBox(NULL, Ex.GetErrorDesc().c_str(), "Archive Demo", MB_OK); }

注意:如果在堆上使用new分配了CFile对象,那么在关闭文件后必须删除它。Close将文件指针设置为NULL。

使用CXArchive类序列化对象非常简单。对于基本类型,只需使用插入/提取操作符。对于更复杂的类型,请调用它们的Serialize方法,但不要忘记将CXArchive参数传递给它们。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485