VS2010/MFC编程入门之四十五(MFC常用类:CFile文件操作类)

上一节中鸡啄米讲了 定时器Timer的用法,本节介绍下文件操作类CFile类的使用。

       CFile类概述

       如果你学过C语言,应该知道文件操作使用的是文件指针,通过文件指针实现对它指向的文件的各种操作。这些文件操作函数中有的最终还是调用了操作系统的API函数或者处理过程与之类似,例如在Windows系统中,fread函数就调用了API函数ReadFile。

       Windows系统的API函数除了ReadFile,还有CreateFile、WriteFile等函数。而MFC基于面向对象的思想,将这些Windows API函数封装到了CFile类中,实现对文件的打开、关闭、读、写、获取文件信息等操作。使用CFile类对文件进行操作非常便捷。

       CFile类的成员函数

       CFile( );
       CFile(HANDLE hFile);
       CFile(LPCTSTR lpszFileName,UINT nOpenFlags);

       以上三个成员函数都是CFile的构造函数,用于构造CFile对象。参数hFile为要关联到CFile对象的文件的句柄。参数lpszFileName为要关联到CFile对象的文件的相对路径或者绝对路径;参数nOpenFlags为文件访问选项的组合,通过各选项的按位或运算实现组合,下面的5个表列出了nOpenFlags参数可能取的选项:

       下面的文件访问模式选项表中只能选择一个进行组合,默认取CFile::modeRead。

取值描述
CFile::modeRead只读方式访问文件
CFile::modeWrite写入方式访问文件
CFile::modeReadWrite读写方式访问文件

       下面的文件共享模式选项表中也只能选择一个进行组合,默认的共享模式是CFile::shareExclusive。

取值描述
CFile::shareDenyNone允许其他进程对文件进行读写
CFile::shareDenyRead不允许其他进程读取文件
CFile::shareDenyWrite不允许其他进程写文件
CFile::shareExclusive禁止其他进程对文件的所有访问

       下面的文件创建模式选项列表中可选择第一个或两者都选进行组合。

取值描述
CFile::modeCreate如果文件不存在则创建文件,而如果存在则将它关联到此CFile对象并将长度截取为0
CFile::modeNoTruncate如果文件不存在则创建文件,而如果存在则将它关联到此CFile对象而不进行截取

       注意,选择CFile::modeNoTruncate时需要与CFile::modeCreate一起使用,即CFile::modeCreate | CFile::modeNoTruncate。

       另外,还有一个文件缓冲选项列表和一个文件安全选项。文件缓冲选项不太常用,鸡啄米这里就不讲了,有兴趣的可以查阅MSDN。文件安全选项是CFile::modeNoInherit,意为禁止子进程继承使用此文件。

       当然,在实际使用时,以上各个表并不是都要用到,大家可以根据自己的需要选择用哪个表,选择哪个选项。

       virtual BOOL Open(LPCTSTR lpszFileName,UINT nOpenFlags,CFileException* pError = NULL);

       打开文件。它通常与默认构造函数CFile::CFile()一起使用。参数lpszFileName和nOpenFlags同构造函数。参数pError为指向文件异常对象的指针,默认为NULL。

       virtual void Close( );

       关闭文件。如果你没有在执行析构函数前调用此成员函数关闭文件,则析构函数会为你关闭。

       virtual UINT Read(void* lpBuf,UINT nCount);

       读取文件数据到缓存。参数lpBuf是由用户提供的指向接收文件数据的缓存的指针;参数nCount为读取的最大字节数。返回值是实际读取到缓存的字节数,如果到达文件尾则返回值可能会小于nCount,此时继续读取的话,会返回0,所以通常我们都会判断返回值是否小于nCount或者等于0来确定是否到达文件尾。

       virtual void Write(const void* lpBuf,UINT nCount);

       将缓存中的数据写入文件。参数lpBuf也是由用户提供,指向包含写入数据的缓存的指针;参数nCount为缓存中要被写入文件的数据的字节数。

       virtual ULONGLONG Seek(LONGLONG lOff,UINT nFrom);

       在一个打开的文件中重定位文件指针。参数lOff为文件指针移动的字节个数,为正数时表示向文件尾移动,为负数时表示向文件开头移动;参数nFrom为lOff的基准位置,即由nFrom位置开始移动lOff个字节,它可以取下面几个值中的一个:

       CFile::begin       从文件开头开始移动
       CFile::current    从文件指针的当前位置开始移动 
       CFile::end          从文件尾开始移动

       文件打开时,文件指针被置于0,即文件开头处。

       如果此函数成功则返回文件指针的位置。

       void SeekToBegin( );

       将文件指针移动到文件开头。它等价于Seek( 0L, CFile::begin )。

       ULONGLONG SeekToEnd( );

       将文件指针移动到文件末尾。返回值是文件的字节长度。它等价于CFile::Seek( 0L, CFile::end )。

       virtual ULONGLONG GetLength( ) const;

       获取文件的字节长度。

       virtual void SetLength(ULONGLONG dwNewLen);

       改变文件的长度。参数dwNewLen为文件的新长度,它可能比文件的当前长度值要大或者小,文件会相应的被扩展或截取。

       virtual CString GetFileName( ) const;

       获取文件名称。

       virtual CString GetFilePath( ) const;

       获取文件的绝对路径。

       virtual CString GetFileTitle( ) const;

       获取文件的显示名称。举个例子,与GetFileName区分一下,如果你系统中的文件不显示扩展名,则它获取到的文件名称就不包含扩展名,否则就显示扩展名。

       virtual ULONGLONG GetPosition( ) const;

       获取文件指针的当前位置。

       static void PASCAL Remove(LPCTSTR lpszFileName,CAtlTransactionManager* pTM = NULL);

       删除文件。参数lpszFileName为要删除的文件路径,可以是相对路径、绝对路径或者网络路径;参数pTM指向一个CAtlTransactionManager对象。

       static void PASCAL Rename(LPCTSTR lpszOldName,LPCTSTR lpszNewName,CAtlTransactionManager* pTM = NULL);

       重命名文件。参数lpszOldName为老的文件路径;参数lpszNewName为新的文件路径;参数pTM指向一个CAtlTransactionManager对象。实际上此函数的意义已经不只是重命名文件,还可以移动文件到其他目录下,例如,lpszOldName取"d:\\1.txt",lpszNewName取"e:\\2.txt",这样可以将D盘中的1.txt文件转移到E盘并重命名为2.txt。

       CFile类应用实例

       这里鸡啄米只给大家演示几个简单的代码片段,从这些代码片段中熟悉CFile类的文件操作。

       实例一:构造CFile对象时就打开文件,然后向文件中写入数据,最后以Seek函数移动文件指针,读取文件内容。

C++代码
  1. char writeBuffer[500];     // 要写入的数据的缓存   
  2. char readBuffer[500];      // 存放读取数据的缓存   
  3. LONGLONG lOff = 0;         // 文件指针的偏移量,也是读取到的数据的总字节数  
  4. // 构造CFile对象,同时以创建和读写的方式打开文件E:\1.txt   
  5. CFile file(_T("e:\\1.txt"), CFile::modeCreate | CFile::modeReadWrite);   
  6.   
  7. // 将写入数据的缓存中每个字节都赋值为字符c   
  8. memset(writeBuffer, 'c'sizeof(writeBuffer));   
  9. // 将数据写入到文件中   
  10. file.Write(writeBuffer, sizeof(writeBuffer));   
  11.   
  12. while (true)   
  13. {   
  14.     // 以文件开头为基准,移动文件指针到lOff的位置   
  15.     file.Seek(lOff, CFile::begin);   
  16.     // 读取100个字节的数据到存放读取数据的缓存的readBuffer + lOff位置处   
  17.     int nRet = file.Read(readBuffer + lOff, 100);   
  18.     // 根据实际读取的字节数,增加文件指针的移动量   
  19.     lOff += nRet;   
  20.     // 如果读取数据时返回值小于指定的100,说明已到文件尾,跳出循环   
  21.     if (nRet < 100)   
  22.         break;   
  23. }   
  24.   
  25. // 关闭文件   
  26. file.Close();  

       实际上,在Write函数和Read函数执行后,文件指针会自动移动到最后操作的位置,所以其实上面的代码中无须使用Seek函数再去手动移动文件指针。这将在下面的实例二中体现出来。

       实例二:构造CFile对象,然后使用Open成员函数打开文件,再写入一个结构体数组,最后读取出来。

       先贴上结构体的定义:

C++代码
  1. struct student   
  2. {   
  3.     int  nNum;     
  4.     float fScore;   
  5. };  

       下面是文件操作的代码片段:

C++代码
  1. student s1[2];   // 存放要写入文件的数据   
  2. student s2[2];   // 存放从文件读取的数据   
  3. CFile file;      // CFile对象   
  4. int nReadBytes = 0;   // 从文件中读取到的总字节数   
  5.   
  6. // 为s1数组各元素赋值   
  7. s1[0].nNum = 22;   
  8. s1[0].fScore = 91.5;   
  9. s1[1].nNum = 23;   
  10. s1[1].fScore = 85;   
  11.   
  12. // 以创建、读写方式打开文件E:\1.txt   
  13. if (file.Open(_T("E:\\1.txt"), CFile::modeCreate | CFile::modeReadWrite))   
  14. {   
  15.     // 写入数据s1结构体数组   
  16.     file.Write(s1, sizeof(s1));   
  17.     // 因为上面调用Write以后文件指针在文件尾,所以需要将其移动到文件开头   
  18.     file.SeekToBegin();   
  19.   
  20.     while (true)   
  21.     {   
  22.         // 读取数据到s2   
  23.         int nRet = file.Read((BYTE*)s2 + nReadBytes, sizeof(student));   
  24.         // 计算已经读取到的总字节数   
  25.         nReadBytes += nRet;   
  26.         // 如果读取数据时返回值小于指定的sizeof(student),则说明已到文件尾,跳出循环   
  27.         if (nRet < sizeof(student))   
  28.             break;   
  29.     }   
  30.   
  31.     // 关闭文件   
  32.     file.Close();   
  33. }  

       本节内容就到这里,如果有其他语言的文件操作的经验的话,应该还是比较简单的。鸡啄米很高兴能在大家的编程入门之路上贡献自己一点微薄的力量。



FC常用及其成员函数 CRuntimeClass结构 在CRuntimeClass结构中定义了名、对象所占存储空间的大小、的版本号等成员变量及动态创建对象、派生关系判断等成员函数。每一个从CObject派生的都有一个CRuntimeClass结构同它关联,以便完成在运行时得到对象的信息或基的信息。 要使用CRuntimeClass结构,必须结合使用RUNTIME_CLASS()宏和其他有关运行时型识别的MFC宏。 CCmdTarget (1)消息发送 MFC应用程序为每个CCmdTarget派生创建一个称为消息映射表的静态数据结构,可将消息映射到对象所对应的消息处理函数上。 (2)设置光标 BeginWaitCursor() 将光标改为沙漏形状; EndWaitCursor() 将光标改回到之前的形状; RestoreWaitCursor()用于将光标还原为等待状态。 (3)支持自动化 CCmdTarget支持程序通过COM接口进行交互操作,自动翻译COM接口的方法。 CWinThread 由CCmdTarget派生,主要工作是创建和处理消息循环。 CWinApp 从CWinThread派生,成员函数InitApplication()、InitInstance()、Run()。 在InitInstance()函数中,创建了一个单文档模板或多文档模板(CDocTemplate)的对象,并且在文档模板的构造函数中,系统定义的宏RUNTIME_CLASS创建了文档对象,框架窗口对象和视图对象. 在MFC应用程序中有且仅有一个CWinApp派生的对象,代表程序运行的主线程,代表应用程序本身。 CWnd 由CCmdTarget直接派生,是MFC中最基本的GUI对象。公共变量m_hWnd用于存放供API函数调用的窗口句柄。 CframeWnd 从CWnd派生而来,主要用来掌管一个窗口。其对象是一个框架窗口,包括边界、标题栏、菜单、最大化按钮、最小化按钮和一个激活的视图。常用成员函数: GetActiveDocument():得到当前文档的指针。 GetActiveView(): 得到当前视图的指针。 SetActiveView(): 激活一个视图。 GetTitle(): 得到框架窗口的标题。 SetTitle(): 设置框架窗口的标题。 SetMessageText(): 设置状态栏文本。 CDocument 从CCmdTarget派生,作为用户文档的基,代表了用户存储或打开一个文件。主要功能是把对数据的处理从对用户的界面处理中分离出来,同时提供一个与视图交互的接口。常用的成员函数有: OnNewDocument(): 建立新文档。 OnOpenDocument(): 打开一个文档。 OnCloseDocument(): 关闭文档。 OnSaveDocument(): 保存文档。 UpdateAllView(): 通知所有视图文档被修改。 SaveModified(): 设置文档修改标志。 CView 从CWnd派生而来,是MFC视图和用户视图的基。CWnd::Invalidate()或CWnd::InvalidateRect()可以刷新视图。常用函数有: GetDocument(): 视图对象访问文档对象中的数据的. OnDraw(): 这个函数有一个指向CDC的指针参数, 通过它可能直接调用CDC上显示数据和图形. 在应用程序窗口出现在及大小发生变化时, 系统将自动调用OnDraw函数 OnInitialUpdate(): 作一些初始化工作. 程序员的主要工作 (1) 重写WinApp派生的虚函数InitInstance.在这个函数中,按自己的需要创建和显示窗口. (2) 在CDocument的派生中,声明程序所需的数据和对这些数据进行必要操作的接口函数. (3) 在CViwe的派生中编写处理消息的代码.如果在消息处理中需要文档的数据,应该调用该的成员函数GetDocument来获取文档对象,然后通过文档对象的接口函数对文档中的数据进行操作. (4) 在CViwe的派生中的OnDraw函数中编写窗口重绘时的代码. Gilbert觉得以上是很大的, 下面介绍一些小: CRect 矩形,拥有四个成员变量:top, left, bottom, right。分别表是左上角和右下角的坐标。可以通过以下的方法构造: CRect( int l, int t, int r, int b ); 指明四个坐标 CRect( const RECT& srcRect ); 由RECT结构构造 CRect( LPCRECT lpSrcRect ); 由RECT结构构造 CRect( POINT point, SIZE size ); 有左上角坐标和尺寸构造 CRect( POINT topLeft, POINT bottomRight ); 有两点坐标构造 它的几个成员函数: int Width( ) const; 得到宽度 int Height( ) const; 得到高度 CSize Size( ) const; 得到尺寸 CPoint& TopLeft( ); 得到左上角坐标 CPoint& BottomRight( ); 得到右下角坐标 CPoint CenterPoint( ) const; 得当中心坐标 此外矩形可以和点(CPoint)相加进行位移,和另一个矩形相加得到“并”操作后的矩形。 CPoint 点的坐标,有两个成员变量:x, y。可以和另一个点相加。 CString 表示可变长度的字符串。使用CString可不指明内存大小,CString会根据需要自行分配。几个成员函数: GetLength 得到字符串长度 operator + 相当于strcat Compare 比较 CompareNoCase 不区分大小写比较 MakeUpper 改为小写 MakeLower 改为大写
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值