七、MFC序列化机制和序列化类对象

一、文件操作相关类

CFile类,文件操作类,封装了关于文件读写等操作

        CFile::Open

        CFile::Write/Read

        CFile::Close

        CFile::SeekToBegin/SeekToEnd/Seek

1、创建项目

(1)创建(Win32控制台)项目(MFCFile)

(2)编写程序

#include <afxwin.h>
#include <iostream>
using namespace std;

void File()
{
	CFile file;
	file.Open("E:\\VS2010\\Test07\\file.txt", CFile::modeCreate|CFile::modeReadWrite);
	char bufWrite[256] = "hello file";
	file.Write(bufWrite, strlen(bufWrite));
	
	file.SeekToBegin();
	char bufRead[256]={0};
	file.Read(bufRead, 256);
	cout<<"Buf: "<<bufRead<<endl;
    file.Close();
}

int main()
{
	File();
	return 0;
}

二、序列化基本类型

        以二进制流的形式将数据写入硬盘文件

1、相关类

(1)CFile类,文件操作类

(2)CArchive类,归档类,完成内存数据的读写

        数据 《--》 CArchive 《--》 磁盘

2、序列化机制的使用

(1)创建或打开文件 CFile::Open

(2)定义归档类对象 CArchive ar;

(3)数据序列化(存储/写入) ar<<数据

(4)数据反序列化(加载/读取) ar>>数据

(5)关闭归档类对象 ar.Close()

(6)关闭文件 CFile::Close()

3、创建项目

(1)创建(Win32控制台)项目(MFCSerial)

(2)编写程序

#include <afxwin.h>
#include <iostream>
using namespace std;

void Store()	//序列化(存储/写入)数据
{	
	CFile file;
	file.Open("E:\\VS2010\\Test07\\serial.txt", CFile::modeCreate|CFile::modeWrite);
	
	CArchive ar(&file, CArchive::store, 4096);	//归档类对象,维护缓冲区
	
	long age = 18;
	ar<<age;
	float score = 88.5;
	ar<<score;
	CString strName = "zhangsan";
	ar<<strName;

	ar.Close();
	file.Close();
}

void Load()	//反序列化(加载/读取)数据
{	
	CFile file;
	file.Open("E:\\VS2010\\Test07\\serial.txt", CFile::modeRead);

	CArchive ar(&file, CArchive::load, 4096);	//归档类对象,维护缓冲区

	long age = 0;
	ar>>age;
	float score = 0;
	ar>>score;
	CString strName = "";
	ar>>strName;

	ar.Close();
	file.Close();

	cout<<"age: "<< age <<endl;
	cout<<"score: "<< score <<endl;
	cout<<"name: "<< strName <<endl;
}

int main()
{
	Store();
	Load();
	return 0;
}

 4、序列化的实现

class CArchive
{
    ...
    enum Mode(store=0, load=1, ...);
    BOOL m_nMode;    //访问方式    
    int m_nBufSize;            //buff的大小
    CFile* m_pFile;            //操作文件的对象
    BYTE* m_lpBufCur;            //当前指针位置
    BYTE* m_lpBufMax;            //buff尾地址
    BYTE* m_lpBufStart;          //buff起始地址
}

CFile file;
file.Open( "E:\\VS2010\\Test07\\serial.txt", CFile::modeCreate | CFile::modeWrite );
CArchive ar(&file, CArchive::store, 4096) === CArchive::CArchive(&file,0, 4096)
{
  m_nMode = CArchive::store; // 0
  m_pFile = &file;//“E:/....serial.txt”
  m_nBufSize = 4096;
  m_lpBufStart = new BYTE[m_nBufSize];
  m_lpBufMax = m_lpBufStart + 4096;
  m_lpBufCur =  m_lpBufStart;
}

long age = 18;
ar << age === CArchive::operator<<(age)//函数内部this为&ar
{
  if (m_lpBufCur + sizeof(LONG) > m_lpBufMax) 
  {
    Flush();
  }
  *m_lpBufCur = age;
  m_lpBufCur += sizeof(LONG); 
}

float score = 88.5;
ar << score === CArchive::operator<<(score)//函数内部this为&ar
{
  if (m_lpBufCur + sizeof(float) > m_lpBufMax) 
  {
    Flush();
  }
  *m_lpBufCur = score;//88.5 
  m_lpBufCur += sizeof(float);
}

CString name = "zhangsan";  
ar << name === CArchive::operator<<(name)//函数内部this为&ar
{
  AfxWriteStringLength(ar, 8 )
  {
    ar<<(unsigned char)nLength;//8
  }
  Write(name, 8)//函数内部this为&ar
  {
    memcpy_s(m_lpBufCur, (size_t)(m_lpBufMax - m_lpBufCur), name, 8);
    m_lpBufCur += 8;
  }
}

ar.Close( )//函数内部this为&ar
{
  Flush()//函数内部this为&ar
  {
    &file->Write(m_lpBufStart, ULONG(m_lpBufCur - m_lpBufStart));
    m_lpBufCur = m_lpBufStart;//重置当前指向
  }
}

              m_lpBufCur 
 18 88.5 8 zhangsan|
|--------------------------------------------------------------------|
|                                                                    |
m_lpBufStart     

二、序列化类对象

1、序列化类对象使用

(1)类必须派生自CObject

(2)类内必须添加申明宏 DECLARE_SERIAL(theClass)

(3)类外i必须添加实现宏 IMPLEMENT_SERIAL(theClass, baseClass, 1)        //最后一个参数为类本版,可以填写任意值

(4)必须重写虚函数 Serialize()

2、编写程序

class CMyDoc:public CDocument
{
	DECLARE_SERIAL(CMyDoc)
public:
	CMyDoc(int age=0, float score=0.0, CString name=""):m_nAge(age), m_fScore(score), m_strName(name){};
	virtual void Serialize(CArchive& ar);

public:
	int m_nAge;
	float m_fScore;
	CString m_strName;
};
IMPLEMENT_SERIAL(CMyDoc, CDocument, 1)	//
	void CMyDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		ar<<m_nAge<<m_fScore<<m_strName;
	}
	else
	{
		ar>>m_nAge>>m_fScore>>m_strName;
	}
}

void Store()	//序列化(存储/写入)数据
{	
	CFile file;
	file.Open("E:\\VS2010\\Test07\\serial.txt", CFile::modeCreate|CFile::modeWrite);
	CArchive ar(&file, CArchive::store, 4096);	//归档类对象,维护缓冲区
	CMyDoc data(18, 88.8, "zhang san");
	ar<<&data;
	ar.Close();
	file.Close();
}

void Load()	//反序列化(加载/读取)数据
{	
	CFile file;
	file.Open("E:\\VS2010\\Test07\\serial.txt", CFile::modeRead);
	CArchive ar(&file, CArchive::load, 4096);	//归档类对象,维护缓冲区
	CMyDoc* pData=NULL;
	ar>>pData;
	ar.Close();
	file.Close();
	cout<<"age: "<< pData->m_nAge <<endl;
	cout<<"score: "<< pData->m_fScore <<endl;
	cout<<"name: "<< pData->m_strName <<endl;
}


int main()
{
	Store();
	Load();
	return 0;
}

 3、实现过程

CFile file;
file.Open("E:\\VS2010\\Test07\\serial.txt", CFile::modeCreate|CFile::modeWrite);
CArchive ar(&file, CArchive::store, 4096);//归档类对象,维护缓冲区。
CMyDoc data(18, 88.8, "zhang san");
ar << &data === operator<<(ar, const &data)
{
  ar.WriteObject(&data)//函数内部this为&ar
  {
    CRuntimeClass* pClassRef = &data->GetRuntimeClass();//文档类静态变量
    WriteClass(pClassRef);//将类的相关信息(类名/类大小/类版本)存入ar维护的buff中
    (&data)->Serialize(ar)//函数内部this为&data
    {
      ar << this->m_age << this->m_score << this->m_name; //序列化基本类型变量
    }
  }
}

CFile file;
file.Open( "E:\\VS2010\\Test07\\serial.txt", CFile::modeRead );
CArchive ar( &file, CArchive::load, 4096 );//维护一个buff,大小4096字节
CMyDoc* pdata = NULL;
ar >> pdata === operator>>(ar, pdata) 
{
  pdata = ar.ReadObject(RUNTIME_CLASS(CMyDoc))//函数内部this为&ar
  {
    CRuntimeClass* pClassRef = ReadClass(RUNTIME_CLASS(CMyDoc),...);
           //从文件读取 类的相关信息,和 RUNTIME_CLASS(CMyDoc)中信息进行比对,
           //如果相同返回RUNTIME_CLASS(CMyDoc),如果不同返回NULL
    CObject*pOb = RUNTIME_CLASS(CMyDoc)->CreateObject();
           //动态创建CMyDoc类的对象,并返回对象地址
    pOb->Serialize(ar)//函数内部this为刚刚创建的CMyDoc类对象(pOb)
    {
      ar >> m_age >> m_score >> m_name;//反序列化基本类型变量
    }
    return pOb;
  }
}

 程序源代码:https://download.csdn.net/download/liutit/86738811

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值