1 / 42

第 9 章 MFC 的文件处理机制

第 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 类实现文件的读写;

tiger-nolan
Télécharger la présentation

第 9 章 MFC 的文件处理机制

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第9章 MFC的文件处理机制 9.1 CFile类 9.2 CArchive类 9.3 对象的序列化 9.4 宏DECALRE_SERIAL和IMPLEMENT_SERIAL 9.5 MFC文件命令的默认处理流程

  2. FILE structure Stores information about current state of stream; used in all stream I/O operations • MFC的文件处理机制主要有两种: • 通过CFile类实现文件的读写; • 通过对象的序列化(Serialization)实现数据的存储和读写

  3. 序列化的基本思想:一个类应该能够对自己的成员变量的数据进行读写操作,对象可以通过读操作而重新创建。由于CObject类提供了保存和加载对象状态的基本功能,所以一般类的对象都具备将状态值写入磁盘或从磁盘中读出的方法,这种对象的保存和恢复的过程称为序列化。 对象成员(派生自CObject) 内存地址 内存 磁盘 文件

  4. 9.1 CFile类 CFile类中包含了大量的文件操作函数, 1)用户可以使用CFile类实现文件的read、write、append、delete等操作。 2)相对于其他的文件操作方式,CFile更显得直接和自由。 3) 与C/C++中的文件操作方式接近

  5. 9.1 CFile类 1. CFile类常用的成员函数(表9-1) 2. 文件的创建和打开 创建CFile类的对象,并使其与磁盘文件之间建立关系。 CFile的构造函数: CFile::CFile() CFile::CFile(int hFile); CFile::CFile(LPCTSTR lpszFileName, UINT nOpenFlags ); 文件名(字符串常量) 文件打开模式

  6. 9.1 CFile类 表9-2 几种常用的文件创建及打开方式

  7. 长度=0 例 9-1 长度!=0

  8. 9.1 CFile类 偏移字节数 偏移起点位置 3. 文件的读写 读写位置的定位: LONG CFile::Seek(LONG lOff, UINT nFrom); 表 9-3nFrom的取值 void CFile::SeekToBegin() void CFile::SeekToEnd()

  9. 9.1 CFile类 待写数据的字节数 待写数据的缓冲区 文件的写操作 void CFile::Write(const void * lpBuf, UINT nCount); 例 9-2

  10. 9.1 CFile类 读缓冲区指针 读取的字节数 文件的读操作 UINT CFile::Read(void * lpBuf, UINT nCount);

  11. 例9-3

  12. 9.1 CFile类 4. CFile的派生类CMemFile 将一块内存区域当作文件来实现读写操作,便于在程序的独立模块之间交换数据。

  13. 9.1 CFile类 5. CFileFind类——查找文件 例 9-7

  14. 9.1 CFile类 文件属性的访问

  15. 9.2 CArchive类 • 为什么引入CArchive类? • 为了在磁盘文件中保存应用程序类对象,并通过读取在内存中复原它们。 • 如何实现类对象的存储和读写? • -类的序列化(Serialization)机制,自动化的存储机制,保存对象,动态恢复对象。 • - 形如:ar << a << b << … << z; ar >> a >> b >> … >> z;

  16. File App 9.2 CArchive类 Write • 为什么不使用CFile类来实现? • -类的成员比较复杂(访问属性,继承,嵌套其他的类对象),因此存储也变得复杂。 • - 复原这些对象(动态地创建对象)也需要一些机制来实现。 Read

  17. 9.2 CArchive类 1. 运算符重载 • 为了便于文件的读写操作,CArhive重载了两个运算符,对基本数据类型和CObject的派生类读写予以支持: • 插入符 << • 提取符 >>

  18. 2. 与CFile的关系 包装了CFile

  19. 9.2 CArchive类 • BOOL CArchive::IsLoading() • -当CArchive类处于读状态时,返回TRUE • BOOL CArchive::IsStoring() • -当CArchive类处于写状态时,返回TRUE CFile操作完毕,不要忘记调用CFile::Close() 同理,CArchive操作完毕,也要调用CArchive::Close()

  20. 9.2 CArchive类 例 9-4

  21. 9.3 对象的序列化 1. 序列化的基本概念 序列化(Serialization):是OOP中Object数据的存储和恢复的一种文件读写机制。 对象→字节流,打包 字节流→对象,解包 对象的这种存储技术称为序列化。

  22. 写入时,依据嵌套关系依次调用自己的“保存”成员函数,完成数据的写入操作。写入时,依据嵌套关系依次调用自己的“保存”成员函数,完成数据的写入操作。 • 读取时,根据嵌套关系实现自身数据的读取操作。 数据的解包过程 数据的打包过程

  23. 9.3 对象的序列化 2. MFC的Serialize函数 virtual void CObject::Serialzie(CArchive& ar); 在标准的MFC应用程序的读写过程中,程序首先调用文档类的序列化函数Serialize()。

  24. 9.3 对象的序列化

  25. 9.3 对象的序列化 3. MFC应用程序的序列化过程

  26. 视图类中定义的菜单命令响应函数

  27. 9.3 对象的序列化 4. 序列化的顺序 • 对于嵌套对象,必须由外到内调用各个对象的序列化函数; • 写入顺序与读取顺序必须相同。 例 9-5

  28. 响应文件菜单的打开与保存命令 本例中的CLetter不能解决动态对象的序列化问题。

  29. 9.3 对象的序列化 5. Serialize函数的局限性 • 只能顺序读写文件,不能随机操作文件; • 只能一次性读写文件的所有部分,不能部分读取文件的内容; • 只能操作二进制文件,不能处理文本文件; • 不能操作数据库文件; • 不能共享式操作文件。

  30. 9.4 宏DECLARE_SERIAL与IMPLEMENT_SERIAL 序列化的机制,要求可以动态地创建对象,而派生自CObject类的子类不具备动态创建能力,因此需要为其增加动态创建能力。另外,重载>>运算符,用于读取对象创建信息。 为此,MFC采用一对宏: DECLARE_SERIAL & IMPLEMENT_SERIAL DECLARE_SERIAL( class_name ) • Remarks • DECLARE_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.

  31. 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);

  32. 9.4 宏DECLARE_SERIAL与IMPLEMENT_SERIAL IMPLEMENT_SERIAL( class_name, base_class_name, wSchema) Remarks Generates 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; }

  33. 9.4 宏DECLARE_SERIAL与IMPLEMENT_SERIAL CArchive::ReadObject Reads object data from the archive and constructs an object of the appropriate type.

  34. 9.4 宏DECLARE_SERIAL与IMPLEMENT_SERIAL • CONCLUSION: • 从CObject派生,以便重载Serialize() • 在.h文件中使用DECLARE_SERIAL,在.cpp中使用IMPLEMENT_SERIAL • 必须定义一个无参的构造函数,满足对象动态创建的需要 • 因为序列化与Document类紧密相关,且从其Serialize()开始,故程序中的数据应作为Document类的成员。

  35. 9.4 宏DECLARE_SERIAL与IMPLEMENT_SERIAL

  36. 9.4 宏DECLARE_SERIAL与IMPLEMENT_SERIAL 例 9-6 例 9-6a 文件

  37. 9.5 MFC文件命令的默认处理流程 1. 文件打开 菜单命令File->New 菜单命令File->Open OnNewDocument(…) OnOpenDocument(…) GetFile(…) 构造CArchive对象 DeleteContents(…) DeleteContents(…) SetModifiedFlag(FALSE) Serialize(…) SetModifiedFlag(FALSE) 文档对象

  38. 9.5 MFC文件命令的默认处理流程 1. 文件打开

  39. 9.5 MFC文件命令的默认处理流程 2. 保存文件 菜单命令File->Save 菜单命令File->Save As OnSaveDocument(…) GetFile(…) 构造CArchive对象 DeleteContents(…) Serialize(…) SetModifiedFlag(FALSE) 文件保存完成

  40. 9.5 MFC文件命令的默认处理流程 可以重载CDocument类的OnOpenDocument和OnSaveDocument成员函数,从中获取文件名。如 详见例fileDemo

More Related