⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 13.1 使用 carchive类对文件进行读写操作.txt

📁 网上第一本以TXT格式的VC++深入详解孙鑫的书.全文全以TXT格式,并每一章节都分了目录,清晰易读
💻 TXT
字号:
13.1 使用 CArchive类对文件进行读写操作

本章首先介绍一种新的读写文件的方式:使用 MFC提供的 CArchive类来实现。 CArchive类没有基
类。我们知道,一个对象一旦被构造,它就存活于内存中了,当其生命周期结束后,该对象就要被
销毁。我们可以利用 CArchive类将对象数据保存到永久设备(例如磁盘文件)上,这样,即使应用程
序关闭,再次重启后,仍可以从磁盘文件中读取对象数据,然后在内存中重新构建相应的对象。让
对象数据持久性的过程就称之为串行化(或称为序列化〉。
读者可以认为一个 CArchive对象就是一种二进制流。就像一个输入/输出流一样,一个 CArchive
对象与一个文件相关,并允许带缓冲机制的数据写入和读取。与输入/输出流不同的是,后者处理的
是 ASCII码字符序列,而一个 CArchive对象以一种有效的、非冗余的格式处理二进制对象数据。
在程序中使用 CArchive对象时有几点需要注意,首先是在创建 CArchive对象之前必须先创建一个 
CFile类或其派生类对象,并且因为存档对象既可以用来加载数据,也可以用来保存数据,所以必须
确保这个 CFile类对象的打开方式与该存档(*'chive)对象的加载/保存状态相一致。当构造了一个 
CArchive对象后,就可以将它与一个代表某个打开文件的 CFile类对象或其派生类对象相关联,但
应注意,一个文件(即 CFile对象)只能与
→个活动的存档对象相关联。 
CArchive对象不仅可以处理基本类型的数据,还可以处理 CObject类的派生类对象。 CArchive类重
载了提取(>>)和插入(<<)操作符,它们既支持基本类型,也支持'CObject类的派生类,为用户提供
了一种方便的对象存档编程接口。其中提取(>>)操作符是从存档对象加载 CObject类型和基本类型
的数据:插入(<<)操作符是将 CObject类型和基本类型的数据存储到存档对象中。在 CArchive类中,
这两种操作符分别都有多种重载形式(如例 13-1代码所示)。通过这些重载的函数,我们可以利用 
CArchive对象来完成文件的读写操作。 
例13-1 

friend CArchive& operator >>( CArchive& ar, CObject *& pOb );. 
CArchive& operator >>( BYTE& by ); 
CArchive& operator >>( WORD& w ); 

CArchive类的构造函数的原型声明如下所示: 
CArchive( CFile* pFile, UINT nMode , int nBufSize = 4096 , void* lpBuf = NULL ) ; 
该构造函数具有三个参数,其含义分别如下所述: 
. pFile 
指向文件对象的指针,该文件对象是持久数据的最终未源或目的地。 
. nMode 
. 指定对象是被用来加载的,还是用来保存的标志。取值可以是如表 13.1所示值之一。

表13.1 nMode参数取值
取值 说明  
CArchive::load  从存档对象中装载数据。要求CFile对象具有读取访问许可  
CArchive::store  将数据保存到存档对象中。要求CFiJe对象具有写入访问许可 
CArchive::bNoFlushOnDelete  禁止存档对象析构时自动调用存档对象的F\ush操作。如果设置了此
标志,那么在存档 对象析构前必须显式地调用其Close函数。否则,数据将被破坏  

. nBufSize 
指定内部文件缓冲区的大小,以字节为单位。默认的缓冲区大小是4096字节。 
. lpBuf 
可选指针,指向用户提供的大小为nBufSize的缓冲区。如果未指定这个参数,那么存档对象将从应
用程序的局部堆中分配一块缓冲区,并且该对象销毁时将释放这块内存。但是存档对象并不会释放
用户提供的缓冲区。所以,如果指定了这个参数,就要手工地释放这块内存。
下面将介绍使用CArchive类读写文件的具体过程。为方便起见,本章将在第11章己有程序的基础上
继续添加功能。首先打开第 11章己有的Graphic工程,为该工程的主菜单增加一个子菜单,菜单名
称为:文件操作。然后,为其添加两个菜单项,并分别为它们添加相应的命令响应函数,本例让 
CGraphicView类接收这些菜单项的命令响应。这两个新添菜单项的E、名称,以及相应的响应函数名
称如表13.2所示。
表 13.2新添菜单项属性及晌应函数名称

ID  菜单名称 响应函数  
IDM FILE WRITE  写入文件  OnFileWrite  
IDM FILE READ  读取文件  OnFileRead  

然后在OnFileWrite函数中添加如例 13-2所示的代码。 ~IJ 13-2 
void CGraphicView ; ;OnFileWrite () 

// TODO: Add your command handler code here 
//构造CFile文件对象 
CFile file(" 1. txt" , CFile::modeCreate | CFile::modeWrite}; 

//构造存档对象 
CArchive ar(&file, CArchive::store); 
int i=4; 
char ch=' a ' ; 
float f=1.3f; 
 CString str(nhttp://www.sunxin.orgn}; 
//保存数据 
ar<<i<<ch<<f<<str; 
在上述例 13-2所示代码中,首先构建了一个CFile类型的文件对象: file。接着构造了一个CArchive
类型的对象:ar,其构造函数的第一个参数就是与该存档对象相关联的文件对象 (file),第二个参数
是模式标志,对于保存操作,应该选择CArchive::store标志。因为 CArchive类的构造函数的后两
个参数都有默认值,所以不用为它们赋值。接下来,定义了一个整型变量(0、一个字符型变量 (ch)、
一个浮点型变量(f)和一个CString类型的对象 (s位),并为它们赋了相应的值。最后,调用CArchive
对象重载的插入(<<)操作符将数据保存到文件中。
在C/C++中,浮点数在默认情况下被定义为double类型。如果希望指定 
float类型的数值,需要在该数值后要加上字母f。
运行Graphic程序,单击【文件操作写入文件】菜单项,然后,在Graphic程序所在目录下可以发
现多了一个名为"1.四"的文件。下面再利用CArchive类实现对文件的读取操作,在OnFileRead函数
中添加如例 13-3所示代码。
例3-3 
void CGraphicview::OnFileRead(} 
// TODO: Add your command handler code here 
//构造CFile文件对象 
CFile file ( "1. txt n, CFile: :modeRead) ; 
//构造存档对象 
CArchive ar(&file,CArchive::load); 
int i; 
char ch; 
float f; 
CString str; 
CString strResult; 

//读取数据 
ar>>i>>ch>>f>>str; 
strResult . Format( "%d,%c,%f.%S" ,i,ch, f,str) ; 
MessageBox(strResult) ; 
在上述例 13-3所示代码中,同样地,首先定义了一个 CFile类型的文件对象: file , 并且该文件
对象按照读取方式 ( CFile::modeRead )打开。接着,构造了一个 CArchive对象 :ar,其构造函数
的第一个参数就是与该存档对象相关联的文件对象,第二个参数是模式标志,因为现在是加载数据,
所以将其设置为 CArchive ::load。接下来,定义了一个整型变量(i)、一个字符型变量 ( ch )、
一个浮点型变量(f)和一个 CString类型的对象 ( str ) , 用于保存从文件中读取的数据。再定义
了一个 CString类型的对象 : strResult,用来保存读取数据格式化后的结果。这时就可以利用 
CArchive类提供的提取操作符 (>>)加载数据。注意,对象保存的顺序和提取的顺序必须一致。然后
对读取到的数据进行格式化,最后使用 MessageBox函数将所读取的数据显示出来。
运行 Graphic程序,单击【文件操作_读取数据】菜单项,程序即可弹出如图 13.1所示消息框,可
以看到读取的结果是正确的。
图 13 .1显示读取数据的消息框

通过上面的例子,读者可以发现,对存档对象来说,无论什么类型的数据,都可以使用插入C<d操作
符将其保存到文件中,使用提取 (>>)操作符从文件中加载这些数据,操作非常方便。 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -