一、

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和串行化的更多相关文章

  1. Lua文件操作和串行化

    function n_serialize(data) if type(data)=="number" then io.write(data,"\n") else ...

  2. MFC用串行化实现文档存储和读取功能

    在面向对象的程序设计中,一般都是用二进制文件来保存文档资料.在VC++中控制和使用文件流的方法很多,MFC程序设计中常用的有两种方法:用CFile对象存储和读取文件:利用串行化存取文件.其中用CFil ...

  3. MFC【6】文件I/O和串行化

    文件输入和输出(I/O)服务是所有操作系统的主要工作.Microsoft Windows提供了各种API函数用来读.写和操作磁盘文件.MFC将这些桉树和CFile类融合在面对对象的模型里.其中CFil ...

  4. MFC 文件I/O和串行化

    1.枚举所有文件夹(递归) void EnumerateFolders () { WIN32_FIND_DATA fd; HANDLE hFind = ::FindFirstFile (_T (&qu ...

  5. MFC如何生成一个可串行化的类

    一.MFC允许对象在程序运行的整个过程中持久化的串行化机制 (1)串行化是指向持久化存储媒介(如一个磁盘文件)读或写对象的过程. (2)串行化用于在程序运行过程时或之后修复结构化数据(如C++类或结构 ...

  6. VC++ MFC如何生成一个可串行化的类

    一.MFC允许对象在程序运行的整个过程中持久化的串行化机制(1)串行化是指向持久化存储媒介(如一个磁盘文件)读或写对象的过程.(2)串行化用于在程序运行过程时或之后修复结构化数据(如C++类或结构)的 ...

  7. MFC六大核心机制之四:永久保存(串行化)

    永久保存(串行化)是MFC的重要内容,可以用一句简明直白的话来形容其重要性:弄懂它以后,你就越来越像个程序员了! 如果我们的程序不需要永久保存,那几乎可以肯定是一个小玩儿.那怕我们的记事本.画图等小程 ...

  8. Java 对象的串行化(Serialization)

    1.什么是串行化 对象的寿命通常随着生成该对象的程序的终止而终止.有时候,可能需要将对象的状态保存下来,在需要时再将对象恢复.我们把对象的这种能记录自己的状态以便将来再生的能力.叫作对象的持续性(pe ...

  9. QDataStream类参考(串行化数据,可设置低位高位,以及版本号),还有一个例子

    QDataStream类提供了二进制数据到QIODevice的串行化. #include 所 有成员函数的列表. 公有成员 QDataStream () QDataStream ( QIODevice ...

随机推荐

  1. Redis之父九条编程忠告

    最近在学习redis,特地了解了一下redis之父Salvatore Sanfilippo ,而看到了一篇优秀的文章,总解分享之 个人解读总结如下 取巧编程品质key word:  过硬的编码能力 快 ...

  2. eShopOnContainers 看微服务 ②:配置 启动

    一.什么是docker Docker 是一个开源项目,通过把应用程序打包为可移植的.自给自足的容器(可以运行在云端或本地)的方式,实现应用程序的自动化部署. 使用 Docker 的时候,需要创建一个应 ...

  3. Linux 关机、重启 命令

    重启命令:1.reboot2.shutdown -r now 立刻重启(root用户使用)3.shutdown -r 10 过10分钟自动重启(root用户使用) 4.shutdown -r 20:3 ...

  4. python:选房抽签小工具

    1.房间号和姓名写在house_name.xls的house标签页中[注意!名字均不要改动]2.运行house.py3.当前同目录下会生成result.xls,即为结果:程序运行过程中不要打开该文件, ...

  5. JavaScript 的基础学习(一)

    JavaScript概述 JavaScript的历史 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名ScriptEase.( ...

  6. 201772020113 李清华《面向对象程序设计(java)》第三周学习总结

    一.测试题反思: 这次的测试题暴露出我在学习上的很多问题:首先,编程能力非常薄弱,编程题目只写出了第一个程序,还因为小问题通不过测试,以后一定要多上手练习,多阅读示例程序.其次,对理论知识的掌握不全面 ...

  7. keil mdk5安装

  8. wiredtiger--初学数据恢复

    启动mongodb是failed,日志如下 1.解压wirdtiger包 tar -vxf wiredtiger-3.1.0.tar.bz2 -C /home/wiredtiger/ 2.安装snap ...

  9. CentOS6.8 使man支持显示中文

    1.安装显示中文的man命令 wget https://src.fedoraproject.org/repo/pkgs/man-pages-zh-CN/manpages-zh-1.5.1.tar.gz ...

  10. Java 学习笔记提高篇

    Java笔记(提高篇)整理   主要内容: 面向对象 异常 数组 常用类 集合 IO流 线程 反射 Socket编程 1.  面向对象 1.1包 用来管理Java中的类, 类似文件夹管理文件一样. 因 ...