Upload
ena
View
149
Download
5
Embed Size (px)
DESCRIPTION
第 9 章 MFC 的文件处理机制. 9.1 CFile 类 9.2 CArchive 类 9.3 对象的序列化 9.4 宏 DECALRE_SERIAL 和 IMPLEMENT_SERIAL 9.5 MFC 文件命令的默认处理流程. FILE structure. Stores information about current state of stream; used in all stream I/O operations. MFC 的文件处理机制主要有两种: 通过 CFile 类实现文件的读写; - PowerPoint PPT Presentation
Citation preview
第 9 章 MFC 的文件处理机制
9.1 CFile 类9.2 CArchive 类9.3 对象的序列化9.4 宏 DECALRE_SERIAL 和
IMPLEMENT_SERIAL
9.5 MFC 文件命令的默认处理流程
MFC 的文件处理机制主要有两种:1) 通过 CFile 类实现文件的读写;2) 通过对象的序列化 (Serialization) 实现数据
的存储和读写
FILE structureStores information about current state of stream; used in all stream I/O operations
序列化的基本思想:一个类应该能够对自己的成员变量的数据进行读写操作,对象可以通过读操作而重新创建。由于 CObject 类提供了保存和加载对象状态的基本功能,所以一般类的对象都具备将状态值写入磁盘或从磁盘中读出的方法,这种对象的保存和恢复的过程称为序列化。
内存 磁盘
对象成员(派生自CObject )
文件内存地址
9.1 CFile 类CFile 类中包含了大量的文件操作函数,1) 用户可以使用 CFile 类实现文件的 read 、 write 、append 、 delete 等操作。2) 相对于其他的文件操作方式, CFile 更显得直接和自由。3) 与 C/C++ 中的文件操作方式接近
1. CFile 类常用的成员函数 ( 表 9-1)
2. 文件的创建和打开
创建 CFile 类的对象,并使其与磁盘文件之间建立关系。CFile 的构造函数:CFile::CFile()
CFile::CFile(int hFile);
CFile::CFile(LPCTSTR lpszFileName, UINT nOpenFlags );
文件名 ( 字符串常量 ) 文件打开模式
9.1 CFile 类
9.1 CFile 类
打开方式 说明CFile::modeCreate 如果文件已经存在,则长度置 0
CFile::modeNoTruncate与 modeCreate组合使用,如果文件已存在,则其长度不为 0
CFile::modeRead 只读方式打开CFile::modeReadWrite 读写方式CFile::modeWrite 只写方式CFile::ShareExclusive 独占方式打开
表 9-2 几种常用的文件创建及打开方式
9.1 CFile 类3. 文件的读写读写位置的定位:LONG CFile::Seek(LONG lOff, UINT nFrom);
偏移字节数 偏移起点位置
nFrom的取值 说明CFile::begin 文件首CFile::current 当前位置CFile::end 文件尾
表 9-3 nFrom 的取值
void CFile::SeekToBegin()
void CFile::SeekToEnd()
9.2 CArchive 类
为什么引入 CArchive 类?-为了在磁盘文件中保存应用程序类对象,并通过读取在内存中复原它们。如何实现类对象的存储和读写?- 类的序列化( Serialization )机制,自动化的存储机制,保存对象,动态恢复对象。- 形如: ar << a << b << … << z; ar >> a >> b >> …
>> z;
为什么不使用 CFile 类来实现?- 类的成员比较复杂(访问属性,继承,嵌套其他的类对象),因此存储也变得复杂。- 复原这些对象 ( 动态地创建对象 ) 也需要一些机制来实现。
FileApp Write
Read
9.2 CArchive 类
9.2 CArchive 类
BOOL CArchive::IsLoading()
- 当 CArchive 类处于读状态时,返回 TRUE
BOOL CArchive::IsStoring()
- 当 CArchive 类处于写状态时,返回 TRUE
CFile 操作完毕,不要忘记调用 CFile::Close()
同理, CArchive 操作完毕,也要调用 CArchive::Close()
9.3 对象的序列化
序列化 (Serialization) :是 OOP 中 Object 数据的存储和恢复的一种文件读写机制。
对象→字节流,打包字节流→对象,解包对象的这种存储技术称为序列化。
1. 序列化的基本概念
9.3 对象的序列化
2. MFC 的 Serialize 函数virtual void CObject::Serialzie(CArchive& ar);
在标准的 MFC 应用程序的读写过程中,程序首先调用文档类的序列化函数 Serialize() 。
9.3 对象的序列化5. Serialize 函数的局限性
1)只能顺序读写文件,不能随机操作文件;2)只能一次性读写文件的所有部分,不能部分读取文件
的内容;3)只能操作二进制文件,不能处理文本文件;4)不能操作数据库文件;5)不能共享式操作文件。
9.4 宏 DECLARE_SERIAL 与 IMPLEMENT_SERIAL
序 列 化 的 机 制 , 要 求 可 以 动 态 地 创 建 对 象 , 而 派 生 自CObject 类的子类不具备动态创建能力,因此需要为其增加动态创建能力。另外,重载 >> 运算符,用于读取对象创建信息。
为此, MFC 采用一对宏:DECLARE_SERIAL & IMPLEMENT_SERIAL
DECLARE_SERIAL( class_name )
RemarksDECLARE_SERIAL generates the C++ header code necessary for a
CObject-derived class that can be serialized.
If DECLARE_SERIAL is included in the class declaration, then
IMPLEMENT_SERIAL must be included in the class
implementation.
The DECLARE_SERIAL macro includes all the functionality of
DECLARE_DYNAMIC and DECLARE_DYNCREATE.
9.4 宏 DECLARE_SERIAL 与 IMPLEMENT_SERIAL
DECLARE_SERIAL( class_name )
#define DECLARE_SERIAL(class_name) \
DECLARE_DYNCREATE(class_name) \
friend CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb);
9.4 宏 DECLARE_SERIAL 与 IMPLEMENT_SERIAL
IMPLEMENT_SERIAL( class_name, base_class_name, wSchema )RemarksGenerates the C++ code necessary for a dynamic CObject-derived class with run-time access to the class name and position within the hierarchy.
#define IMPLEMENT_SERIAL(class_name, base_class_name, wSchema) \
CObject* PASCAL class_name::CreateObject() { return new class_name; }
IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema,
class_name::CreateObject) \
CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb){
pOb = (class_name*)ar.ReadObject(RUNTIME_CLASS(class_name));return ar;
}
9.4 宏 DECLARE_SERIAL 与 IMPLEMENT_SERIAL
CArchive::ReadObject Reads object data from the archive and constructs an object of the appropriate type.
9.4 宏 DECLARE_SERIAL 与 IMPLEMENT_SERIAL
CONCLUSION :
1) 从 CObject 派生,以便重载 Serialize()
• 在 .h 文件中使用 DECLARE_SERIAL ,在 .cpp 中使用IMPLEMENT_SERIAL
• 必须定义一个无参的构造函数,满足对象动态创建的需要1) 因为序列化与 Document 类紧密相关,且从其 Serialize() 开
始,故程序中的数据应作为 Document 类的成员。
9.5 MFC 文件命令的默认处理流程
菜单命令 File->Open
OnOpenDocument(…)
GetFile(…)构造 CArchive 对象
DeleteContents(…)
Serialize(…)
SetModifiedFlag(FALSE)
1. 文件打开
菜单命令 File->New
OnNewDocument(…)
DeleteContents(…)
SetModifiedFlag(FALSE)
文档对象
菜单命令 File->Save As
OnSaveDocument(…)
GetFile(…)构造 CArchive 对象
DeleteContents(…)
Serialize(…)
SetModifiedFlag(FALSE)
9.5 MFC 文件命令的默认处理流程2. 保存文件
菜单命令 File->Save
文件保存完成