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 ...
随机推荐
- IDLE的GUI交互模式下完美清屏
IDLE的GUI交互模式下完美清屏==============================================================================1.首先把 ...
- phpexcel导入导出
先下载类文件,将类文件放到lib下,然后到入口文件定义一个新的的路径,以便引入文件. <?php namespace app\index\controller; use think\Con ...
- 可以作为瘟到死(windows)路径的字符
!#$%&""()+-0123456789;=@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz[]^_`{}~
- python sqlparse 各种 token
https://blog.csdn.net/qq_39607437/article/details/79620383 import sqlparse def look(statement): prin ...
- android rc文件分析
service vold /system/bin/vold \ --blkid_context=u:r:blkid:s0 --blkid_untrusted_context=u:r:bl ...
- Linux学习-linux系统下安装jdk和tomcat,以及遇到的问题清单
安装JDK 1. 在usr目录下建立java安装目录 cd /usr mkdir java 2.下载jdk包 登录网址:http://www.oracle.com/technetwork/java ...
- 利用CCS3渐变实现条纹背景
本文摘自<CSS揭秘>中国工信出版集团 难题: 不论是在网页设计中,还是在其他传统媒介中(比如杂志和墙纸等),各种尺寸.颜色.角度的条纹图案在视觉设计中无处不在.要想在网页中实现条纹图案, ...
- logrotate-日志切割示例
logrotate是linux系统自带的工具,它可以自动对日志进行截断(或轮循).压缩以及删除旧的日志文件. 1)配置文件示例# cat /wls/wls81/bin/weblogic/wls/app ...
- HDU-1160.FatMouse'sSpeed.(LIS变形 + 路径打印)
本题大意:给定一定数量的数对,每个数保存着一只老鼠的质量和速度,让你求出一个最长序列,这个序列按照质量严格递增,速度严格递减排列,让你输出这个序列的最长长度,并且输出组成这个最长长度的序列的对应的老鼠 ...
- oracle 执行顺序 select查询优化
今天把这几天做的练习复习了一下,不知道自己写得代码执行的效率如何以及要如何提高,于是乎上网开始研究一些材料,现整理如下: 首先,要了解在Oracle中Sql语句运行的机制.以下是sql语句的执行步骤: ...