当前位置: 首页 > 图文教程 > 开发语言 > VC++ > FMD开发文集 -- CArchive原理

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

VC++ 中的 FMD开发文集 -- CArchive原理


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 46 ::
收藏到网摘: n/a

FMD开发文集 -- CArchive原理
作者:冯明德

MFC 提供CArchive类实现数据的缓冲区读写,同时定义了类对象的存储与读取方案。 以下对CArchvie 的内部实现作分析。

1.概述
2.内部数据
3.基本数据读写
4.缓冲区的更新
5.指定长度数据段落的读写
6.字符串的读写
7.CObject派生对象的读写

一.概述

CArchive使用了缓冲区,即一段内存空间作为临时数据存储地,对CArchive的读写都先依次排列到此缓冲区,当缓冲区满或用户要求时,将此段整理后的数据读写到指定的存储煤质。
当建立CArchive对象时,应指定其模式是用于缓冲区读,还是用于缓冲区写。
可以这样理解,CArchive对象相当于铁路的货运练调度站,零散的货物被收集,当总量到达火车运量的时候,由火车装运走。
当接到火车的货物时,则货物由被分散到各自的货主。与货运不同的是,交货、取货是按时间循序执行的,而不是凭票据。因此必须保证送货的和取货的货主按同样的循序去存或取。
对于大型的货物,则是拆散成火车单位,运走,取货时,依次取各部分,组装成原物。

二.内部数据
缓冲区指针 BYTE* m_lpBufStart,指向缓冲区,这个缓冲区有可能是底层CFile(如派生类CMemFile)对象提供的,但一般是CArchive自己建立的。
缓冲区尾部指针 BYTE* m_lpBufMax;
缓冲区当前位置指针 BYTE* m_lpBufCur;
初始化时,如果是读模式,当前位置在尾部,如果是写模式,当前位置在头部:

m_lpBufCur = (IsLoading()) ? m_lpBufMax : m_lpBufStart;
三.基本数据读写

对于基本的数据类型,例如字节、双字等,可以直接使用">>"、"<<"符号进行读出、写入。

//操作符定义捕:	//插入操作CArchive& operator<<(BYTE by);CArchive& operator<<(WORD w);CArchive& operator<<(LONG l);CArchive& operator<<(DWORD dw);CArchive& operator<<(float f);CArchive& operator<<(double d);CArchive& operator<<(int i);CArchive& operator<<(short w);CArchive& operator<<(char ch);CArchive& operator<<(unsigned u);//提取操作CArchive& operator>>(BYTE& by);CArchive& operator>>(WORD& w);CArchive& operator>>(DWORD& dw);CArchive& operator>>(LONG& l);CArchive& operator>>(float& f);CArchive& operator>>(double& d);CArchive& operator>>(int& i);CArchive& operator>>(short& w);CArchive& operator>>(char& ch);CArchive& operator>>(unsigned& u);
下面以双字为例,分析原码

双字的插入(写)

CArchive& CArchive::operator<<(DWORD dw){	if (m_lpBufCur + sizeof(DWORD) > m_lpBufMax) //缓冲区空间不够	Flush(); //缓冲区内容提交到实际存储煤质。	if (!(m_nMode & bNoByteSwap))	_AfxByteSwap(dw, m_lpBufCur); //处理字节顺序	else	*(DWORD*)m_lpBufCur = dw; //添入缓冲区	m_lpBufCur += sizeof(DWORD); //移动当前指针	return *this;}
双字的提取(读)
CArchive& CArchive::operator>>(DWORD& dw){	if (m_lpBufCur + sizeof(DWORD) > m_lpBufMax) //缓冲区要读完了	FillBuffer(sizeof(DWORD) - (UINT)(m_lpBufMax - m_lpBufCur)); //重新读入内容到缓冲区	dw = *(DWORD*)m_lpBufCur;	//读取双字	m_lpBufCur += sizeof(DWORD);	//移动当前位置指针	if (!(m_nMode & bNoByteSwap))	_AfxByteSwap(dw, (BYTE*)&dw); //处理字节顺序	return *this;}
四.缓冲区的更新

以上操作中,当缓冲区将插入满或缓冲区将提取空时,都将对缓冲区进行更新处理。

缓冲区将插入满时调用Flush();
void CArchive::Flush(){	ASSERT_VALID(m_pFile);	ASSERT(m_bDirectBuffer || m_lpBufStart != NULL);	ASSERT(m_bDirectBuffer || m_