友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
VC语言6.0程序设计从入门到精通-第29部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
}
else {
ar 》》 m_strName 》》 m_nType 》》 m_pData; //读取数据
}
}
在上述代码 中,之所以 能对自定义 的类进行插 入和提取运 算,是因为 在添加的
DECLARE_SERIAL()和 IMPLEMENT_SERIAL()宏中包含了对插入和提取运算符的重载 。当
CSampleChildData 对象被写进文件时,这两个宏保证类名和数据一起被写进去 ;而当从文件
中读入时,类名被读进来,相应的类的对象被动态构造,这些也是由这两个宏包含的代码实
现的。当 CSampleChildData 对象被构造后,就可以通过 Serialize() 自动进行串行化,这是由
于 CArchive 的插入和提取运算符对 CObject 类型进行了重载。最后新建的 CSampleChildData
对象的指针即保存在 m_pData 中。根据上面的分析,对于自定义的类,不能对类的实例对象
使用插入和提取运算符,而只能对类的指针进行这样的操作。
(4 )集合类
由于所有的集合类都是从 CObject 类派生出来的,而且集合类都包含了与串行化有关的
宏调用,因此就可以通过调用集合类的 Serialize()成员函数,方便地对集合进行串行化 。例如
一个由 CSampleData 对象组成的 CArray 集合,调用 CArray 的 Serialize()函数,就可以使得每
个 CSampleData 对象的 Serialize()函数被依次调用,从而完成对集合类的序列化。
8。1。3 CArchive 类
在前面的章节中已有关于 CArchive 类的介绍,该类提供了一个类型安全的访问 CFile 对
象(CFile 对象是 Visual C++ 中的基本文件对象,将在 8。2 节中详细介绍)的机制,用于将可
串行化对象写入 CFile 对象或者从中读取可串行化对象 。给定的 CArchive 对象可以存储数据,
也可以加载数据,但不允许同时进行,而且其寿命也只限于将对象写入文件或从文件读取对
·180 ·
…………………………………………………………Page 192……………………………………………………………
第 8 章 文件操作
象的一次性传递。这也就是 MFC 中串行化只能顺序进行的原因。
下面介绍 Carchive 类的一些主要功能。
1.构造函数
Carchive 类通过构造函数从已打开的 CFile 对象中创建可以向该 CFile 对象进行串行化的
新对象。其原型为:
CArchive(
CFile* pFile;
UINT nMode;
int nBufSize = 4096;
void* lpBuf = NULL
);
o 参数 pFile 指向需要进行串行化的 CFile 对象。
o 参数 nMode 设置创建对象的标志,如果设置了这个标志,则必须在销毁前调用 Close
函 数 , 否 则 数 据 将 会 损 坏 。 若 取 值 为 CArchive::load : 从 文 件 中 读 取 数 据 ;
CArchive::store :向文件中保存数据;CArchive::bNoFlushOnDelete :防止 CArchive 对
象在被销毁时自动调用 Flush 函数进行更新。
o 参数 nBufSize 设置缓冲区大小。
o 参数 lpBuf 用于自定义缓冲区,取值为 NULL 则由 CArchive 自行处理。
下面是一段示例代码:
CFile file;
file。Open(〃1。dat〃; CFile::modeWrite); //打开 1。dat 文件进行写操作
CArchive archive(&file; CArchive::stroe);; //创建一个对 file 进行数据保存的文档对象
2 .读写函数
(1)插入运算符(》 )
这两个运算符分别用于保存和读取数据,在原型中可以看到 CArchive 类为许多数据类型
进行了重载,这为数据的串行化提供了基础。
(2 )Read()和 Write() 函数
这两个函数分别从文件中读取或写入原始的字节块。原型为:
UINT Read(
void* lpBuf;
UINT nMax
);
void Write(
const void* lpBuf;
UINT nMax
);
o 参数 lpBuf :给出字节块的指针,用于保存数据或者从中读取数据。
·181 ·
…………………………………………………………Page 193……………………………………………………………
Visual C++ 6。0 程序设计从入门到精通
o 参数 nMax :用于确定最大的读写字节数。
o Read()函数返回值:返回实际读写的字节数。
(3 )Flush() 函数
该函数用于将缓冲区剩余的数据强制写入文件中。原型为:
void Flush( );
注意该函数只保证数据完全传送到指定的 CFile 对象中,而且必须通过 CFile::Close 才能
完成最终向磁盘写入数据的过程。
3 .状态和标志函数
该类函数主要有 IsLoading()和 IsStoring()两个函数,这两个函数分别用于确定 CArchive
对象是否处于读取状态,或者是否处于保存状态。其原型分别为:
BOOL IsLoading( ) const;
BOOL IsStoring( ) const;
4 .Close()函数
该函数用于清空缓冲区,关闭 CArchive 对象,并且将 CArchive 对象与 CFile 对象分离。
其原型为:
void Close( );
8。1。4 加入串行化代码
介绍完串行化的基本内容,本节将讲述如何在文档视图应用程序中添加文档类的串行化
功能的方法来实现文档的保存和读取。
在 MFC 中,文档数据进行串行化的处理过程,同样是通过文档类的 Serialize()函数进行。
下面以选择“文件|另存为”菜单命令为例介绍这个过程。首先 MFC 框架提示用户选取文件
名,并打开对应的 CFile 对象。接着框架创建指向该 CFile 对象的 CArchive 对象。由于是“另
存为”,因此该对象设置为“存储 ”,即 CArchive::store 。然后调用 CDocument 派生类即程序
的文档类中定义的 Serialize()函数,将 CArchive 对象的引用传递给该函数。程序的文档类的
Serialize()函数执行完毕后,框架先销毁 CArchive 对象,再销毁 CFile 对象。
因此,根据上述过程,在文档视图应用程序中进行文档的串行化处理,只需要在文档类
中重载 CDocument::Serialize()函数,对特定的文档数据进行串行化即可实现。下面给出一个
在文档类中加入串行化代码的示例代码。该段代码中 CSampleDoc 类是程序的文档类,它有
一个 CSampleData 类的成员变量指针,用于保存文档数据。示例演示了 CSampleDoc 类如何
将 CSampleData 类的文档数据串行化。
1.CSampleData 类的声明
具体代码如下:
class CSampleData : public CObject
{
public:
·182 ·
…………………………………………………………Page 194……………………………………………………………
第 8 章 文件操作
//定义的公共数据类型
CString m_strName;
int m_nType;
CSampleData();
virtual ~CSampleData();
//定义串行化的宏
DECLARE_SERIAL(CSampleData)
// 串行化虚函数
virtual void Serialize(CArchive &ar);
};
2 .CSampleData 类的实现
具体代码如下:
//实现串行化的宏
IMPLEMENT_SERIAL(CSampleData; CObject; 0)
//初始化
CSampleData::CSampleData()
{
m_nType=0;
m_strName=〃〃;
}
CSampleData::~CSampleData()
{
}
// 串行化函数
void CSampleData::Serialize(CArchive &ar)
{
//基类的串行化
CObject::Serialize(ar);
if (ar。IsStoring())
{
//存储数据
arm_strName;
}
}
3 .CSampleDoc 类的声明
具体代码如下:
class CSampleDoc : public CDocument
{
protected: // create from serialization only
CSampleDoc();
DECLARE_DYNCREATE(CSampleDoc)
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSampleDoc)
public:
virtual BOOL OnNewDocument();
virtual void Serialize(CArchive& ar);
//}}AFX_VIRTUAL
// Implementation
public:
CSampleData *m_pData; //这里加入自定义文档数据
virtual ~CSampleDoc();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
·184 ·
…………………………………………………………Page 196……………………………………………………………
第 8 章 文件操作
protected:
// Generated message map functions
protected:
//{{AFX_MSG(CSampleDoc)
// NOTE the ClassWizard will add and remove member functions here。
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
4 .CSampleDoc 类的实现
具体代码如下:
CSampleDoc::CSampleDoc()
{
// TODO: add one…time construction code here
// 初始化数据
m_pData=NULL;
}
CSampleDoc::~CSampleDoc()
{
}
BOOL CSampleDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
//创建新的文档数据
if (m_pData!=NULL) delete m_pData;
m_pData=new CSampleData;
CString m_str;
return TRUE;
}
·185 ·
…………………………………………………………Page 197……………………………………………………………
Visual C++ 6。0 程序设计从入门到精通
/////////////////////////////////////////////////////////////////////////////
// CSampleDoc serialization
// CSampleDoc 的串行化函数
void CSampleDoc::Serialize(CArchive& ar)
{
if (ar。IsStoring())
{
// TODO: add storing code here
//保存 m_pData
arm_pData;
}
}
8。2 文件 CFile 类
在 8。1 节中介绍了如何在文档视图应用程序中加入串行化并进行文件的保存和打开。这
种串行化方法也有诸多局限,不能实现灵活的文件访问。当程序需要自定义文件操作时,就
需要用到 CFile 类。在 MFC 中,CFile 类处理正常的文件 I/O 操作。CFile 类提供通用二进制
文件操作的接口,是所有 MFC 文件操作类的基础,串行化也是最终通过 CFile 类进行文件处
理的。本节将用多个示例介绍 CFile 类的使用方法,并提供 CFile 类中各种函数的使用参考。
实例 8…1:个人信息录入实例。源代码在光盘中“08实例 8…1PersonData”目录下。
PersonData 示例运行界面如图 8…1 所示。该示例是一个基于对话框的 MFC 应用程序。运
行时先提示程序用户选择个人信息数据文件,比如 PersonData 工程目录下的 test。dat 。打开数
据文件后就进入如图 8…1 所示的界面。在这个界面里左侧的列表框可以添加、删除和选择个
人信息的条目 。当选择定某个人名时,在右侧的“个人信息”栏中显示个人信息的具体内容。
如果要修改某个条目的个人信息,则可以直接编辑对话框右侧的具体内容,然后单击“更新”
按钮即可。
·186 ·
…………………………………………………………Page 198……………………………………………………………
第 8 章 文件操作
图 8…1 PersonData 运行界面
PersonData 演示了如何用 CFile 类对文件进行随机读写。在程序代码中可以看到下面几
个小节中 CFile 类的各种成员函数的使用范例。
PersonData 用结构 PersonInfo 定义每条个人信息的具体成员,其定义如下:
typedef struct PERSONINFO {
char szName'51'; //姓名
char szBirth'31'; // 出生日期
int nSex; //性别,0 为男,1 为女
char szTitle'51'; //职务
char szOffice'201'; //办公室
char szOfficePhone'31'; //办公电话
char szHome'201'; //家庭住址
char szHomePhone'31'; //家庭电话
char szMobilePhone'31'; //手机
char szEMail'101'; //E…mail 地址
} PersonInfo;
PersonData 的主对话框类 CPersonDataDlg 设置了下列几个控件变量,用于显示和修改用
户个人信息,代码如下:
public:
CListBox m_PersonList; //左侧“选择人名”列表框
CString m_szBirth; // “出生日期”输入框
CString m_szEMail; // “E…mail ”输入框
CString m_szHome; // “家庭地址”输入框
CString m_szHomePhone; // “家庭电话”输入框
CString m_szMobilePhone; // “手机”输入框
CString m_szName; // “姓名”输入框
CString m_szOffice; // “办公室”输入框
CString m_szOfficePhone; // “办公电话”输入框
CString m_szSex; // “性别”下拉列表框
·187 ·
…………………………………………………………Page 199……………………………………………………………
Visual C++ 6。0 程序设计从入门到精通
CString m_szTitle; // “职务”输入框
CPersonDataDlg 根据示例要求,添加了各种消息处理函数,至此添加、删除和修改个人
信息的功能完成。这些函数将在 8。2。1 至 8。2。4 小节中结合 CFile 类的使用详细介绍。
8。2。1 打开操作
使用文件之前需要先打开文件,该过程就是通过 Windows API 通知 Windows 系统寻找磁
盘上的指定文件,然后在内存中创建一个与此文件有关的访问句柄,以后所有的文件操作都
需要这个句柄标识操作对象。CFile 类封装了这
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!