第11章文件处理_第1页
第11章文件处理_第2页
第11章文件处理_第3页
第11章文件处理_第4页
第11章文件处理_第5页
已阅读5页,还剩57页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第11章 文件处理在Windows中,各种数据及信息都存储在文件中。因此在Windows下的程序一般情况下都需要对文件进行数据的存储和读取。学习本章,读者可以掌握C+程序文件输入输出的基本方法,以及利用MFC中的CFile类对文件进行操作的基本方法。11.1 文件的输入输出文件的输入输出是文件的基本操作。在C+中,文件的输入输出是十分简单的事情。本节介绍C+中文件的输入输出操作的基本知识。11.1.1 C+对文件操作的支持C+把文件看做是字符序列,也就是说文件是由一个个字符数据顺序组成的。根据数据的组织形式,文件分为文本文件和二进制文件。文本文件的每个字节存放一个ASCII码,代表一个字符。二

2、进制文件则是把内存中的数据,按其在内存中的样子写到磁盘中。文本文件是每个字节存放一个ASCII,即一个字节对应于一个字符,这样可以很方便地进行操作,而二进制文件并不是每一个字节都对应一个字符,因此不可以以字符形式直接进行输出。但是二进制文件比文本文件占用空间小,因此在程序中经常用来保存一些中间结果,这些内容有时需要再次送入内存。在C+中要进行文件的输入输出,需要首先创建一个流,然后将这个流与文件相关联,即打开文件。这时就可以对文件进行操作,操作完成后关闭文件。11.1.2 文件的打开与关闭在利用Visual C+进行文件操作之前都需要首先打开文件。打开文件之后才可以对文件进行操作,当操作结束时

3、还需要关闭文件。下面对文件打开和关闭的基本过程进行介绍。1文件的打开在C+中文件的打开实际上就是将文件与一个流对象关联起来,C+提供了3个标准的流类,3个流类列表如表11.1所示。表11.1 C+的流类名名 称称基基 类类作作 用用ofstreamostream文件的输出文件的输出ifstreamistream文件的输入文件的输入fstreamiostream文件的输入或输出文件的输入或输出在C+中,文件的打开一般需要进行下面几步:(1)建立流对象。C+提供了3个标准的输入输出流,可以利用这些流类建立需要的对象。(2)使用流类的成员函数open()打开文件。其原型如下:void open( c

4、onst char* szName, int nMode, int nProt = filebuf:openprot ); 各个参数的含义分别为:szName表示文件名。nMode表示打开方式,它的取值为表11.2的一个或者几个。表11.2 nMode的取值及其含义需要注意的是当利用此open()函数打开的文件不存在时,应用程序会新建一个文件,然后再进行打开。当需要以一种以上的方式打开文件时,即nMode的取值有多个,需要用“|”连接起来,这样就可以以多种方式打开文件。注意:在Visual C+中使用C+的标准流类,需要包含头文件iostream.h。nMode的取值的取值说说 明明ios:a

5、pp输出追加到文件尾输出追加到文件尾ios:ate查找文件尾查找文件尾ios:in打开文件进行读操作打开文件进行读操作ios:nocreate文件不存在,则打开失败文件不存在,则打开失败ios:noreplace文件存在,打开失败文件存在,打开失败ios:out打开文件进行写操作打开文件进行写操作ios:trunc删除文件后重新新建文件删除文件后重新新建文件ios:binary文件以二进制形式打开文件以二进制形式打开2文件的关闭在对文件的输入输出完成以后,需要关闭文件,即取消流对象和文件之间的关联。文件的关闭需要使用close()函数。close()是流类的成员函数,它的使用非常简单,没有参数

6、,也没有返回值。11.1.3 文本文件的输入和输出在打开文件以后,就可以对文件进行输入操作,即写操作。使用运算符“”,就可以将内容输入到文件。在C+中对屏幕的输出使用的是cout”,其他的含义是完全相同的。【示例11.1】将110这10个整数输入到文件中。新建一个控制台应用程序,编写代码如下:程序运行后,屏幕上并不显示任何内容,因为输出的内容保存在文件中。打开当前目录下的文件num,可以看到文件中的内容如下:12345678910上面的例子是先建立一个输出文件,然后写入数据,最后关闭文件。可以看到文件中已保存了输出的内容。11.1.4 二进制文件的输入和输出任何文件都可以以二进制形式打开,文本

7、文件是字符流,而二进制文件是字节流。在默认情况下,文件的打开方式是以文本文件的形式。如果需要指定以二进制文件打开文件,只需要在open()函数时指定方式为ios:binary方式。对二进制文件的读写有两种方式,一种是使用get()和put()函数,另一种是使用read()和write()函数。这四个函数也可以用于文本文件的读写,其使用方式与二进制文件的使用区别不大。1get()和put()函数的使用get()是输入流类istream的成员函数,它可以从流对象连接的文件中读出数据,每次读取一个字节。put()是输出流类ostream的成员函数,它可以向流对象连接的文件写入数据。get()和put

8、()函数的原型如下:istream& get( unsigned char& ruch );每次读入一个字节,并且放入rush中。ostream& put( char ch );将字符ch写入到文件中。2read()和write()函数的使用read()和write()函数可以用来读写一个块数据,即可以读写结构体、数组等。其原型如下:istream& read( char* pch, int nCount );istream& read( unsigned char* puch, int nCount );istream& read( signe

9、d char* psch, int nCount );这个函数的第一个参数是块数据的首字节地址,第二个参数是读入的字节数。ostream& write( const char* pch, int nCount );ostream& write( const unsigned char* puch, int nCount );ostream& write( const signed char* psch, int nCount );这个函数参数的意义和read()函数的参数的意义完全相同,只不过这个函数是将数据写入文件。【示例11.2】 将存放a到e的5个字符的数组写入文

10、件。新建一个控制台应用程序,编写代码如下:分析:程序运行后,屏幕上并不显示任何内容,因为输出的内容保存在文件中,打开当前目录下的文件num,可以看到文件中的内容如下:abcde本节介绍了在Visual C+中进行文件操作的基本函数和过程。在MFC中对这些操作以C+类的形式进行了封装,使得文件的操作更加简单和方便。在11.2节中将会看到使用MFC封装的文件类进行文件操作的基本方法和过程。11.2 CFile类在MFC中利用C+类的形式封装了对各种各样的文件的操作。其中CFile类是文件操作的基类,提供了对普通文件进行的操作。11.2.1 初识CFile类在MFC中利用C+类的形式封装了对各种各样

11、的文件的操作。常见的类有下面几种。CFile:文件类的基类,封装了二进制磁盘文件的操作。CStdioFile:封装了对缓冲流文件的操作。CMemFile:封装了对内存文件的操作。CShareFile:封装了对共享内存文件的操作。COleStreamFile:封装了使用COMM Istream接口对复合文件的操作。CSocketFile:封装了对Windows Socket提供的操作。说明:CFile类是CObject的派生类,因此它支持串行化操作。在应用中可以使用串行化操作保存文件。CFile类是文件类的基类,它封装了对磁盘文件进行的操作,其成员函数如表11.3所示。表11.3 CFile的主

12、要成员函函 数数说说 明明CFile( LPCTSTR lpszFileName, UINT nOpenFlags );构造函数构造函数virtual BOOL Open( LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL );打开文件打开文件virtual void Close();关闭文件关闭文件virtual UINT Read( void* lpBuf, UINT nCount );读入读入nCount字节大小的内容字节大小的内容DWORD ReadHuge( void* lpBuffer, DWO

13、RD dwCount );读入读入dwCount字节大小的内容字节大小的内容virtual void Write( const void* lpBuf, UINT nCount );写入写入nCount字节大小的内容字节大小的内容void WriteHuge( const void* lpBuf, DWORD dwCount );写入写入dwCount字节大小的内容字节大小的内容virtual LONG Seek( LONG lOff, UINT nFrom );定位到指定位置的定位到指定位置的nFrom处处void SeekToBegin();定位到文件头定位到文件头DWORD SeekTo

14、End();定位到文件尾定位到文件尾virtual DWORD GetLength() const;得到文件大小得到文件大小virtual void SetLength( DWORD dwNewLen );设置文件大小设置文件大小virtual DWORD GetPosition() const;得到文件指针的位置得到文件指针的位置virtual CString GetFileName() const;得到文件名得到文件名static void PASCAL Rename( LPCTSTR lpszOldName, LPCTSTR lpszNewName );修改文件名修改文件名static

15、void PASCAL Remove( LPCTSTR lpszFileName );删除文件删除文件使用CFile类可以方便地进行文件操作,其中文件操作中需要首先打开文件,文件的打开方式是一个需要注意的问题。Open函数中参数 nOpenFlags的常用取值为以下的一个或几个。 CFile:modeCreate:打开文件时,如果文件不存在则新建一个文件。CFile:modeNoTruncate:普通方式打开文件。CFile:modeRead:只读方式打开文件。CFile:modeReadWrite:文件可读可写。CFile:modeWrite:只写方式打开文件。11.2.2 使用CFile类

16、前面介绍了CFile类的基本成员,下面结合实例对CFile类的使用进行介绍。【示例11.3】 在对话框中利用CFile类实现保存在编辑框中输入的内容,单击“显示”按钮后,在文件中保存该内容,并且在另一个对话框中输出文件的所有内容。操作步骤如下:(1)新建一个基于对话框的应用程序。(2)在资源编辑环境中添加两个编辑框和一个按钮控件。(3)添加单击按钮控件的消息映射,编写函数体如下:分析:上面代码首先将编辑框1里面的内容保存在文件的末尾,然后将文件里面的所有内容读出来,显示在编辑框2里面。提示:应预先建立test.txt文件。(4)编译、连接,运行结果如图11.1所示。图11.1 运行结果上面的编

17、辑框2中显示的是文件中的所有内容,在当前文件夹下可以找到“test.txt”文件,以记事本形式打开,可以看到里面内容如下:这是第一次输入这是第二次输入下面进行第三次输入好了,任务完成了本节介绍了使用MFC中封装的文件类进行文件操作的基本方法和步骤。利用CFile类使得对文件的操作更加简单和方便。该类包含了许多常见的操作。正确使用其提供的成员可以使得文件操作十分方便。11.3 CFileFind类CFileFind类是一个从CObject派生来的类。它可以对本地文件和远程文件进行搜索和查找。是一个对文件系统操作常用的类。本节介绍该类的主要成员及其用法。11.3.1 初识CFileFind类CFi

18、leFind类是进行文件查找的类。可以对本地文件和远程文件进行查找。同时可以获取文件的各种信息,例如文件的大小、文件的创建时间、文件的属性等。CFileFind类主要的成员函数及其参数包括下面一些。(1)FindFile()函数,该函数实现文件的查找。其函数原型如下:virtual BOOL FindFile( LPCTSTR pstrName = NULL, DWORD dwUnused = 0 );该函数若返回非0则表明执行成功,0则表明执行不成功。各个参数意义如下所示。pstrName:需要查找的文件名,例:“E:VC+Test.rar”,也可以是NULL表示“*.*。dwUnused:

19、必须为0。说明:在Visual C+中“”表示的是一个“”,因为第一个“”表示的是转义字符。如果要出现两个反斜杠,那么可以写出如下形式:“”。(2)FindNextFile()函数,该函数查找是否还有符合条件的文件。其函数原型如下:virtual BOOL FindNextFile( );该函数返回值非0表示还有符合条件的文件,0表示是最后一个文件。(3)GetCreationTime()函数,查找文件的创建时间。函数原型如下:virtual BOOL GetCreationTime(FILETIME *pFileTime) constvirtual BOOL GetCreationTime(

20、CTime& refTime) const;该函数用来获得查找到的某个文件的创建时间,返回值非0表示获得创建时间操作成功,0表示执行获得创建时间失败。参数意义如下所示。FILETIME*:容纳时间的结构指针。CTime&:容纳时间的对象地址。(4)GetLastAccessTime()函数,得到文件最后被访问的时间。函数原型如下:virtual BOOL GetLastAccessTime(FILETIME *pFileTime) constvirtual BOOL GetLastAccessTime(CTime& refTime) const;该函数用来获得某个文件最

21、后被访问的时间,非0表示执行成功,0表示执行失败。(5)GetFilePath()函数,该函数用来查找文件的绝对路径。函数原型如下:virtual CString GetFilePath() const;该函数用来获得查找到的文件绝对路径,必须在执行了FindNextFile()后该函数才能执行成功。返回的结果是CString对象。(6)GetFileName()函数,该函数可以用来得到文件的全称。函数的原型如下:virtual CString GetFileName() const;该函数用来获得查找到的文件的全称,必须在执行了FindNextFile()后该函数才能执行成功。返回的结果是C

22、String对象,例“Test.rar”。(7)GetFileTitle()函数,可以用来得到文件的名称。函数原型如下:virtual CString GetFileTitle() const;该函数用来获得查找到的文件的名称,必须在执行了FindNextFile()后该函数才能执行成功。返回的结果是CString对象,例“Test”。(8)GetRoot()函数,得到查找文件的根目录,函数原型如下:virtual CString GetRoot() const;该函数用来获得查找到的文件的根目录,必须在执行了FindNextFile()后该函数才能执行成功。返回的结果是CString对象,例

23、“E:”。(9)GetFileURL()函数,查找文件的URL路径。函数原型如下:virtual CString GetFileURL() const;该函数用来获得查找到的文件的URL路径,必须在执行了FindNextFile()后该函数才能执行成功。返回的结果是CString对象,例“file:/E:Test.rar”。(10)GetLength()函数,获取文件的长度。函数原型如下:DWORD GetLength() const;该函数返回值获得查找到的文件的长度,必须在执行了FindNextFile()后该函数才能执行成功。(11)IsHidden() 函数,判断文件属性。函数原型如下

24、:BOOL IsHidden() const;该函数用来判断查找的文件属性是否隐藏文件,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功。(12)MatchesMask函数,查找文件的综合属性。函数原型如下:BOOL MatchesMask(DWORD dwMask) const;该函数用来判断查找的文件的综合属性,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功。dwMask参数表示文件属性的结构,其取值为下面的一种或几种。FILE_ATTRIBUTE_ARCHIVE:档案文件。FILE_ATTRIBUTE_COMPRE

25、SSED:压缩文件。FILE_ATTRIBUTE_DIRECTORY:路径文件。FILE_ATTRIBUTE_NORMAL:正常文件。FILE_ATTRIBUTE_READONLY:只读文件。FILE_ATTRIBUTE_SYSTEM:系统文件。FILE_ATTRIBUTE_TEMPORARY:临时文件。FILE_ATTRIBUTE_HIDDEN:隐藏文件。注意:在上面函数中有些函数必须在执行了FindNextFile()后才能调用。否则程序会产生异常。11.3.2 使用CFileFind类CFileFind函数可以对本地文件进行查找。最常用的例如遍历某个文件夹下的所有文件等。例如,Windo

26、ws自带的资源管理器就可以利用该类来实现。本节结合一个小例子介绍该类的使用。【示例11.4】 利用CFileFind类遍历D:目录下的“test”文件夹下的所有文件。并显示在树视图控件中。具体步骤如下所述。(1)创建一个基于对话框的应用程序。在上面添加一个树视图控件,其ID为IDC_TREE,并且设置控件的样式为有节点前面的“+”号等,样式设置如图11.2所示。图11.2 设置树视图样式(2)在CTestDlg中添加变量如下:CImageList m_imageList;TV_INSERTSTRUCT tvinsert;HTREEITEM hDad;HICON hIcon;(3)在OnInit

27、Dialog()函数中对树视图控件进行初始化工作,包括设置图标等。代码如下:分析:上面的代码对树视图的样式、图标等内容进行了初始化工作。并且显示了第一层图标。但此时需要遍历搜索D:test目录下的所有文件,并将文件名在树视图上显示出来。下面对文件搜索进行介绍。(4)在CTestDlg中添加一个函数实现文件的遍历查找,void Findfile(CString str, HTREEITEM h);函数,在该函数中遍历查找文件,并且将文件目录显示在树视图控件中。代码如下:分析:上面函数利用递归实现文件的遍历。并且将文件目录显示在树视图控件上。需要注意的是当所示的文件为一个目录时要对该目录进行遍历,

28、此时进行搜索时,要保留当前的节点,然后该节点称为父节点,进行显示。搜索结束后再次设置当前节点为刚才保留的同级节点。为了在对话框显示时就搜索文件,可以在上面的OnInitDialog()函数中调用上面的函数。(5)编译、连接,运行结果如图11.3所示。图11.3 运行结果通过上面的实例可以看到CFileFind的具体使用方法,使用CFileFind可以方便地对各种目录下的文件进行搜索。它可以对本地文件和远程文件进行搜索和查找。是一个对文件系统操作时常用的类。在进行文件系统的程序设计中经常使用该类进行文件的查找操作等。11.4 数据的对象化串行化在文档程序设计中曾经介绍了MFC中串行化的概念。所谓

29、的串行化是指微软提供的用于对对象进行文件输入输出的一种机制。在CObject类中提供了串行化的操作,因此使用串行化操作可以方便地实现CFile类的存储问题。11.4.1 CFile类与串行化CFile类是MFC中进行文件操作的类,该类直接从CObject类派生而来。因此该类可以利用串行化进行输入输出。为了实现串行化,可以先了解串行化的知识。所谓的串行化是指将对象存储到介质中,之后可以通过反串行化从这些连续的数据重新构建一个与原始对象状态相同的对象,因此在特定情况下也可以说是得到一个副本。在MFC的主要基类CObject类中提供了对串行化的支持,在使用串行化时,可以首先创建一个CArchive对

30、象,然后使用该对象进行串行化操作。CArchive类在MFC中没有任何基类,该类提供了一个类型安全缓冲机制,用于将可串行化对象写入CFile对象或从中读取可串行化对象。CArchive类的对象是作为串行化对象和存储介质之间的中介。因此在使用CArchive对象前必须先建CFile对象,然后使用该CFile对象定义CArchive对象。下面介绍CFile进行串行化保存和读取的基本过程,数据保存时的基本步骤为:(1)创建一个CFile对象,此时需要创建文件。(2)创建一个CArchive对象,此时需要使用CFile对象,参数为CArchive:store类型。(3)重载Serialize()函数,

31、实现串行化操作。(4)在需要保存的地方调用Serialize()函数,实现保存。上面介绍了CFile进行串行化保存的基本步骤,串行化读取(也称为反串行化)的步骤与保存时的基本步骤类似。只不过创建CArchive对象时指定参数为CArchive:load。CFile可以进行数据的存储和读取,而CArchive从一个更高的层次上进行了数据的管理。这样使得CFile类转换到CArchive类,然后实现串行化操作。在11.4.2节中将看到使用串行化操作的具体的使用过程。说明:CArchive类并不是MFC整个系统中的类,它没有基类。但是在MFC中提供了进行串行化操作异常类:CArchiveExcept

32、ion类。11.4.2 操作实例前面介绍了CFile类与串行化的关系,在实际应用中使用串行化操作可以简化数据的处理过程,使得应用程序更加简单。下面结合具体实例介绍CFile进行串行化的基本过程。【示例11.5】 创建一个基于对话框的应用程序,在上面添加多个编辑框控件实现学生信息的输入。实现数据的保存和读取。具体步骤如下所述。(1)创建一个基于对话框的应用程序。(2)在对话框上添加多个编辑框控件,实现对学生信息的输入。并且利用向导为文本框控件添加变量。控件的ID和添加的变量,以及输入的信息如表11.4所示。表11.4 编辑框的ID和变量控件控件ID变变 量量功功 能能IDC_NAMECStringm_name;姓名姓名IDC_AGEintm_age;年龄年龄IDC_SEXCStringm_sex;性别性别IDC

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论