MFC文件IO和串行化
一、
MFC中CFile对象实现了磁盘文档的读写,但是大部分MFC应用程序的IO服务都使用CArchive对象来完成。不管CFile和Archive输入输出的都是二进制数据,非文本数据。
int a = 0;
CFile file(TEXT("log.txt"), CFile::modeCreate | CFile::modeReadWrite | CFile::modeNoTruncate);
file.Write(&a, sizeof(a));
CArchive ar(&file, CArchive::store);
ar << a ;
上面两种输出方式得到的结果同。
二、
MFC重载了<<和>>运算符,以便能够串行或并行化MFC中的基本数据类型和一些MFC中的非基本数据类型,比如CString。
同时,MFC还允许用户能够创建自己的可串行化类,使它们能够与CArchive的插入提取运算符一起工作。
下面介绍如何编写一个可串行化类:
1.直接或者间接的CObject的派生类。
2.在类的声明中写入MFC的DECLEAR_SERIAL宏,改宏只接收一个参数:类名。
3.重载父类中的Serialize函数,在该函数中串行化派生类的数据成员。
4.如果派生类没有默认构造函数,则需要添加一个。对象并行化时,MFC使用默认构造函数创建对象,并未数据成员赋值。
5.在类的实现中写入MFC的IMPLEMENT_SERIAL宏,该宏接受三个参数:类名,基本类名和模式号。模式号等价于版本号,只要
修改了类的串行化数据格式,模式号也要随之改变。
具体实现如下:
类声明:
class CLine :public CObject
{
public:
DECLARE_SERIAL(CLine);
CLine();
CLine(CPoint from, CPoint to){ m_ptFrom = from; m_ptTo = to; }
virtual void Serialize(CArchive& ar);
~CLine();
protected:
CPoint m_ptFrom;
CPoint m_ptTo;
};
类定义:
IMPLEMENT_SERIAL(CLine, CObject, 1)
void CLine::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
ar << m_ptFrom << m_ptTo;
}
else
{
ar >> m_ptFrom >> m_ptTo;
}
}
三、
如果后续开发过程中,CLine添加了一个持久性数据成员,则需要把版本号增加到2,这样就能够根据不同版本区别串行化到磁盘的CLine对象。
否则,磁盘版本为1的CLine就可能被读入内存版本为2的CLine中。
如何让程序向下兼容既能够读取版本号为1的磁盘上的数据又能够读取版本号为2的磁盘上的数据呢?
可是化模式也就诞生了,可视化模式只是包含VERSIONABLE_SCHEMA标志的模式号,该标志禁止产生CArichiveException,并允许应用程序对不同的模式号
有判断地响应。使用了可视化模式可以给用户提供向下兼容性。
编写一个具有MFC可视化模式支持的可串行化类,一般需要两步:
1. 将IMPLEMENT_SERIAL宏中的模式号与宏VERSIONABLE_SCHEMA相或。
2. 如果从archive加载对象时,需要调用CArchive::GetObjectSchema,该函数返回并行化对象的模式号,同时还需要修改Serialize函数。
具体实现如下
类声明中:
class CLine :public CObject
{
public:
DECLARE_SERIAL(CLine);
CLine();
CLine(CPoint from, CPoint to){ m_ptFrom = from; m_ptTo = to; }
virtual void Serialize(CArchive& ar);
~CLine();
protected:
CPoint m_ptFrom;
CPoint m_ptTo;
COLORREF m_clrLine;
};
类实现中:
IMPLEMENT_SERIAL(CLine, CObject, 2|VERSIONABLE_SCHEMA)
void CLine::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
ar << m_ptFrom << m_ptTo << m_clrLine;
}
else
{
UINT sechema = ar.GetObjectSchema();
switch (sechema)
{
case 1:
ar >> m_ptFrom >> m_ptTo;
m_clrLine = RGB(0, 0, 0);
break;
case 2:
ar >> m_ptFrom >> m_ptTo >> m_clrLine;
break;
default: break;
}
}
}
四、
最后,MFC为CObject指针重载了<< 和 >>符号,但是CObject对象没有重载,所以我们在对一个对象进行串行化时可以直接调用它的Serialize函数,
但是,这样的串行化后的对象将没有版本号。
MFC文件IO和串行化的更多相关文章
- Lua文件操作和串行化
function n_serialize(data) if type(data)=="number" then io.write(data,"\n") else ...
- MFC用串行化实现文档存储和读取功能
在面向对象的程序设计中,一般都是用二进制文件来保存文档资料.在VC++中控制和使用文件流的方法很多,MFC程序设计中常用的有两种方法:用CFile对象存储和读取文件:利用串行化存取文件.其中用CFil ...
- MFC【6】文件I/O和串行化
文件输入和输出(I/O)服务是所有操作系统的主要工作.Microsoft Windows提供了各种API函数用来读.写和操作磁盘文件.MFC将这些桉树和CFile类融合在面对对象的模型里.其中CFil ...
- MFC 文件I/O和串行化
1.枚举所有文件夹(递归) void EnumerateFolders () { WIN32_FIND_DATA fd; HANDLE hFind = ::FindFirstFile (_T (&qu ...
- MFC如何生成一个可串行化的类
一.MFC允许对象在程序运行的整个过程中持久化的串行化机制 (1)串行化是指向持久化存储媒介(如一个磁盘文件)读或写对象的过程. (2)串行化用于在程序运行过程时或之后修复结构化数据(如C++类或结构 ...
- VC++ MFC如何生成一个可串行化的类
一.MFC允许对象在程序运行的整个过程中持久化的串行化机制(1)串行化是指向持久化存储媒介(如一个磁盘文件)读或写对象的过程.(2)串行化用于在程序运行过程时或之后修复结构化数据(如C++类或结构)的 ...
- MFC六大核心机制之四:永久保存(串行化)
永久保存(串行化)是MFC的重要内容,可以用一句简明直白的话来形容其重要性:弄懂它以后,你就越来越像个程序员了! 如果我们的程序不需要永久保存,那几乎可以肯定是一个小玩儿.那怕我们的记事本.画图等小程 ...
- Java 对象的串行化(Serialization)
1.什么是串行化 对象的寿命通常随着生成该对象的程序的终止而终止.有时候,可能需要将对象的状态保存下来,在需要时再将对象恢复.我们把对象的这种能记录自己的状态以便将来再生的能力.叫作对象的持续性(pe ...
- QDataStream类参考(串行化数据,可设置低位高位,以及版本号),还有一个例子
QDataStream类提供了二进制数据到QIODevice的串行化. #include 所 有成员函数的列表. 公有成员 QDataStream () QDataStream ( QIODevice ...
随机推荐
- 算术运算,赋值运算,if语句,while,continue语句
算术运算 print(10 / 3)=3.333333333333 print(10 // 3)=3 print(10 ** 2)=100 赋值运算增量赋值 age=18 age+=1 print(a ...
- python大法好——面向对象
python大法好——面向对象 Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的.本章节我们将详细介绍Python的面向对象编程. 如果你以前没 ...
- Mysql 和 SQLServer 使用SQL差异比较
查询前100条数据 #mysql ; #sqlserver * from table_name ; 从数据库.表 定位表 #mysql写法:库名.表名 select password from Inf ...
- Django 部署(Nginx+uwsgi)
使用 uwsgi 来部署 安装 uwsgi sudo pip install uwsgi --upgrade 使用 uwsgi 运行项目 uwsgi --http :8001 --chdir /pat ...
- css:常见布局问题
一.单列布局 1. 水平居中 1.1 使用inline-block和text-align .parent{text-align:center;} .child{display:inline-block ...
- 机器学习linux系统环境安装
机器学习linux系统环境安装 安装镜像下载 可以自己去ubuntu官方网站按照提示下载amd64的desktop版本 或者考虑到国内镜像站点下载,如tuna,163, ali等 课程使用最新的17. ...
- JAVA条件判断
一.基本if结构 1.流程图 l 输入输出 l 判断和分支 l 流程线 1.1 简单的if条件判断 if(表达式){ //表达式为true,执行{ ...
- 关于$.ajax同步和异步的问题和提交后台的一些问题。
经常有人ajax函数外,定义一个全局变量,并且在返回函数取出一个值用作判断条件,但是这一条件常常失效. var OnOff=0; var checkPhone = function() { var p ...
- Ubuntu16下用virtualbox 安装Windows虚拟机
平时要用Windows系统,但是现在工作都是在Linux下面开发,所以都没装Windows,之前用vm虚拟机比较麻烦, 所以就用virtualbox搞搞: 1.sed -i '$adeb http:/ ...
- 简单的TSQL基础编程格式,存储过程,视图
这里简单整理一下数据库简单的编程,变量定义,赋值,分支语句和循环(这里以Sqlserver),以及存储过程格式 首先是变量定义,赋值,分支语句 --======TSQL数据库基础编程,定义变量,赋值, ...