《6 vc++ 编程技术.ppt》由会员分享,可在线阅读,更多相关《6 vc++ 编程技术.ppt(19页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、V c+V c+编程技术编程技术授课对象:(本科)教 师:廖光忠第六讲文档类对象的持续性及其文档视图结构的高级形式目标:学习使用文件访问和文档类内容:1.访问二进制文件2.访问标准I/O文件3.访问内存文件4.在数据类中实现串行化5.串行化SDI或MDI文档6.例子;访问二进制文件目标目标在一个平面磁盘文件中维护二进制数据。策略策略利用M F C的C F i l e类,该类封装了Windows API中处理二进制文件的函数。步骤步骤1.检查文件是否存在要判断某个文件是否已在磁盘上存在,可以使用静态C F i l e函数GetStatus()。CFileStatus status;if(!CFi
2、le:GetStatus(sFile,status)msg.Format(%s does not exist,sFile);A f x M e s s a g e B o x(m s g);2.创建一个二进制文件为了创建一个可写的二进制文件,首先创建一个C F i l e类对象,然后利用Open()成员函数打开并创建一个文件对象。CFile file;CString msg;CString sFile(Wzd.tmp);if(!file.Open(sFile,CFile:modeCreate|CFile:modeWr i t e)msg.Format(Failed to create%s.,s
3、File);A f x M e s s a g e B o x(m s g);3.使用二进制文件1)写二进制数据到文件中。f i l e.Write(buff e r,sizeof(buff e r);2)关闭文件,销毁文件对象。file.Close();3)打开一个二进制文件进行读操作。if(!file.Open(sFile,CFile:modeRead)msg.Format(Failed to open%s.,sFile);A f x M e s s a g e B o x(m s g);4)获得二进制或其他类型文件的长度。UINT nBytes=file.GetLength();5)使用
4、如下函数之一以改变文件读写的当前位置。f i l e.S e e k To E n d();file.Seek(20,/file offset in bytesCFile:begin);/also CFile:end and CFile:currentf i l e.S e e k To B e g i n()6)利用如下代码从二进制文件中读取数据,其中n B y t e s是实际读取的字节数。若n B y t e s比想要读取的字节数小或者为0,则已到文件结束处。nBytes=file.Read(buff e r,sizeof(buff e r);7)设置文件为只读,使用C F i l e的
5、静态成员函数SetStatus()。我们获取文件当前的任何状态,并加上只读状态标记。if(CFile:GetStatus(sFile,status)s t a t u s.m _ a t t r i b u t e|=0 x 0 1;CFile:SetStatus(sFile,status);8)删除一个文件,使用C F i l e的另外一个静态函数Remove()。CFile:Remove(sFile);访问标准I/O文件目标操作文本文件。策略利用M F C的C S t d i o F i l e类操作文本文件。C S t d i o F i l e从C F i l e类派生,并封装Wind
6、ows API中用来处理文本文件的函数。步骤1.检查一个文件是否存在使用C F i l e类的GetStatus()静态函数,判断一个文本文件是否存在。CFileStatus status;CString sFile(Wzd.txt);if(!CFile:GetStatus(sFile,status)msg.Format(%s does not exist,sFile);A f x M e s s a g e B o x(m s g);2.创建一个文本文件打开一个文本文件以写文本串。本例中,若所找文件无法打开,则创建一个新文件。CStdioFile file;if(!file.Open(sFi
7、le,CFile:modeWrite|CFile:typeTe x t)if(!file.Open(sFile,CFile:modeCreate|C F i l e:m o d e Write|CFile:typeTe x t)CString msg;msg.Format(Failed to create%s.,sFile);3.使用文本文件1)写一个文本串到文件中。f i l e.WriteString(sRecord);2)关闭文件并销毁创建的文件对象。file.Close();3)打开一个文本文件进行读操作。if(!file.Open(sFile,CFile:modeRead|CFile
8、:typeTe x t)msg.Format(Failed to open%s.,sFile);A f x M e s s a g e B o x(m s g);4)定位到文件的头和尾。f i l e.S e e k ToEnd();f i l e.S e e k ToBegin();5)从一个文本文件中读一个文本串。file.ReadString(sRecord);6)删除一个文本文件。CFile:Remove(sFile);访问内存文件目标在内存中生成一个文件,而不是在磁盘上生成一个临时文件。策略使用M F C的C M e m F i l e类,该类是从C F i l e类派生的,封装分配
9、内存的Windows API。步骤1.创建一个内存文件要创始一个内存文件,只要创建一个C M e m F i l e类对象。CMemFile file;创建一个C M e m F i l e类对象自动打开一个内存文件。2.使用内存文件1)写内存文件。f i l e.Write(buff e r,sizeof(buff e r);2)判断内存文件的当前长度。UINT nBytes=file.GetLength();3)使用以下方法定位下次读写的位置。f i l e.S e e k To E n d();file.Seek(20,/file offset in bytesCFile:begin);
10、/also CFile:end and CFile:currentf i l e.S e e k To B e g i n();4)从内存文件中读数据。nBytes=file.Read(buff e r,sizeof(buff e r);5)删除内存文件有两种方法:一是销毁C M e m F i l e类对象,二是设置文件长度为0。file.SetLength(0);在数据类中实现串行化目标目标串行化数据类。策略策略实现从C O b j c t派生过来的数据类的串行化。M F C的C O b j e c t类添加一个虚重载函数到类中,该函数为Serialize()。我们将用我们自己的Seria
11、lize()重载这个Serialize(),使之装入和保存成员变量到磁盘上。步骤1.在数据类中加入Serialize()从M F C的C O b j e c t派生得到用户的数据类。不是从C O b j e c t派生的类不能进行串行化。因为C l a s s Wi z a r d没有提供把C O b j e c t作为类的基类的功能,则需要加进这个基类。class CMyData:public CObject;利用以下格式,在每个数据类中加入Serialize()成员函数。void CMyData:Serialize(CArchive&ar)C O b j e c t:S e r i a l
12、 i z e(a r);int version=1;i f(a r.I s S t o r i n g()/store datae l s e/load data2.串行化简单变量1)要保存数据类中不是从C O b j e c t派生的成员变量,在Serialize()函数的“保存数据”区使用 重载操作符。C O b j e c t:S e r i a l i z e(a r);i f(a r.I s S t o r i n g()/store member variables not derived from CObjectar m_sName;ar 重载操作符。C O b j e c t:
13、S e r i a l i z e(a r);i f(a r.I s S t o r i n g()/store datae l s e/load member variables not derived from CObjectar m_sName;ar m_sComment;3.串行化派生于C O b j e c t的变量调用成员变量的Serialize()函数以保存派生于C O b j e c t的成员变量。/load and store member variables derived from CObjectm _ w z d I n f o.S e r i a l i z e(a
14、r);可以在类的Serialize()函数的调出和保存区中,调用该Serialize()函数,或者在if else 表达式之后调用该Serialize()一次即可。若在变量类中没有实现Serialize(),则应该加上一个。4.串行化数据集1)保存数据集,使用如下语句。nCount=m_WzdInfoList.GetCount();/get number of items inar S e r i a l i z e(a r);注意在这里我们首先保存数据集中工程的数目,然后一步一步地按顺序保存每个工程。2)使用如下语句,装入数据集。/load a list of dataar nCount;w
15、hile(nCount-0)CWzdInfo2*pInfo=new CWzdInfo2;p I n f o-S e r i a l i z e(a r);m _ W z d I n f o L i s t.A d d Ta i l(p I n f o);串行化SDI或MDI文档目标目标利用M F C框架的内建特征串行化S D I和M D I文档到磁盘。策略策略利用文档类中的两个函数实现从磁盘中调出文档或串行化文档到磁盘上。第一个是文档类的Serialize()函数,通过对它编程,系统地调用文档中每个数据类实例的Serialize()成员函数(在前例中,我们已经添加了该成员函数)。第二个是Del
16、eteContents(),用来初始化文档。我们还将编辑一段代码来定制打开文件对话框的文档扩展名。步骤1.使用文档类的Serialize()定位D o c u m e n t类的Serialize()成员函数,如前例一样,在Serialize()函数中填入代码。在此只是简单地串行化文档类的每个成员变量到作为参数所传递过来的存档类参考中。2.使用文档类的DeleteContents()使用C l a s s Wi z a r d,在文档类中加入DeleteContents()重载函数。当选择F i l e/N e w或者F i l e/O p e n菜单命令时,该重载函数被自动调用,提供一个重新
17、初始化文档的机会。void CWzdDoc:DeleteContents()/called by new and open document/opportunity to initialize the data collections/that make up your documentwhile(!m_WzdInfo1List.IsEmpty()delete m_WzdInfoList.RemoveHead();C D o c u m e n t:D e l e t e C o n t e n t s();3.指定文件扩展名为了定制在应用程序中打开供用户选择文件名的文件对话框,可以在字符串资源表中编辑一个字符串。定位定义文档类型的字符串。在本例中,I D为I D C _ W Z D T Y P E。对这个字符串所需的修改如下面灰底和下划线的部分。nWzdnWzdnWzd Files(*.wzd)n.wzdnWzd.DocumentnWzd Document
限制150内