转自:http://www.jizhuomi.com/software/234.html

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++代码
char writeBuffer[];     // 要写入的数据的缓存
char readBuffer[]; // 存放读取数据的缓存
LONGLONG lOff = ; // 文件指针的偏移量,也是读取到的数据的总字节数
// 构造CFile对象,同时以创建和读写的方式打开文件E:\1.txt
CFile file(_T("e:\\1.txt"), CFile::modeCreate | CFile::modeReadWrite); // 将写入数据的缓存中每个字节都赋值为字符c
memset(writeBuffer, 'c', sizeof(writeBuffer));
// 将数据写入到文件中
file.Write(writeBuffer, sizeof(writeBuffer)); while (true)
{
// 以文件开头为基准,移动文件指针到lOff的位置
file.Seek(lOff, CFile::begin);
// 读取100个字节的数据到存放读取数据的缓存的readBuffer + lOff位置处
int nRet = file.Read(readBuffer + lOff, );
// 根据实际读取的字节数,增加文件指针的移动量
lOff += nRet;
// 如果读取数据时返回值小于指定的100,说明已到文件尾,跳出循环
if (nRet < )
break;
} // 关闭文件
file.Close();
 

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

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

先贴上结构体的定义:

C++代码
struct student
{
int nNum;
float fScore;
};

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

C++代码
student s1[];   // 存放要写入文件的数据
student s2[]; // 存放从文件读取的数据
CFile file; // CFile对象
int nReadBytes = ; // 从文件中读取到的总字节数 // 为s1数组各元素赋值
s1[].nNum = ;
s1[].fScore = 91.5;
s1[].nNum = ;
s1[].fScore = ; // 以创建、读写方式打开文件E:\1.txt
if (file.Open(_T("E:\\1.txt"), CFile::modeCreate | CFile::modeReadWrite))
{
// 写入数据s1结构体数组
file.Write(s1, sizeof(s1));
// 因为上面调用Write以后文件指针在文件尾,所以需要将其移动到文件开头
file.SeekToBegin(); while (true)
{
// 读取数据到s2
int nRet = file.Read((BYTE*)s2 + nReadBytes, sizeof(student));
// 计算已经读取到的总字节数
nReadBytes += nRet;
// 如果读取数据时返回值小于指定的sizeof(student),则说明已到文件尾,跳出循环
if (nRet < sizeof(student))
break;
} // 关闭文件
file.Close();
}

本节内容就到这里,如果有其他语言的文件操作的经验的话,应该还是比较简单的。

其它参考:https://blog.csdn.net/niteip/article/details/7726381

VS2010-MFC(MFC常用类:CFile文件操作类)的更多相关文章

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

    上一节中鸡啄米讲了定时器Timer的用法,本节介绍下文件操作类CFile类的使用. CFile类概述 如果你学过C语言,应该知道文件操作使用的是文件指针,通过文件指针实现对它指向的文件的各种操作.这些 ...

  2. 文件操作类CFile

    CFile file; CString str1= L"写入文件成功!"; wchar_t *str2; if (!file.Open(L"Hello.txt" ...

  3. php的多功能文件操作类

    本类为文件操作类,实现了文件的建立,写入,删除,修改,复制,移动,创建目录,删除目录,列出目录里的文件等功能,路径后面别忘了加"/" 创建指定路径下的指定文件 * @param s ...

  4. php文件操作类

    <?php /** *本类为文件操作类,实现了文件的建立,写入,删除,修改,复制,移动,创建目录,删除目录 * 列出目录里的文件等功能,路径后面别忘了加"/" */ clas ...

  5. [C#] 常用工具类——文件操作类

    /// <para> FilesUpload:工具方法:ASP.NET上传文件的方法</para> /// <para> FileExists:返回文件是否存在&l ...

  6. ansible笔记(5):常用模块之文件操作(二)

    ansible笔记():常用模块之文件操作(二) 文件操作类模块 find模块 find模块可以帮助我们在远程主机中查找符合条件的文件,就像find命令一样. 此处我们介绍一些find模块的常用参数, ...

  7. asp.net文件操作类

    /** 文件操作类 **/ #region 引用命名空间 using System; using System.Collections.Generic; using System.Text; usin ...

  8. android 文件操作类简易总结

    android 文件操作类(参考链接) http://www.cnblogs.com/menlsh/archive/2013/04/02/2997084.html package com.androi ...

  9. Ini文件操作类

    /// <summary> /// Ini文件操作类 /// </summary> public class Ini { // 声明INI文件的写操作函数 WritePriva ...

随机推荐

  1. Windows server 2016 / Windows 10关于域管理员帐号权限不足的问题

    今天在测试windows server 2016的域创建时,当安装结束之后,发现使用Administrator用户进行操作时,被提示了权限不足这个问题.于是我在百度上查找了一番之后,找到了解决方法. ...

  2. 读书笔记二、ndarray的数据类型

    dtype(数据类型)是一个特殊的对象,它含有ndarray将一块内存解释为特定数据类型所需的信息: import numpy as np arr1=np.array([1,2,3],dtype=np ...

  3. thrift 的一些相关知识

    thrift是一个很好用的跨语言的rpc框架. 但是其也有一些需要注意的问题: 第一: 发现其对于类型检查没有那么严格:    最近工作中发现是可以把一个int类型直接付给string,而没有任何wa ...

  4. js 数组 常用方法

    let arr=[{a:1},{a:2},{a:3}];//forEach 数组循环// 返回void arr.forEach(i=>{ // i为arr中的元素 }) //filter 数组过 ...

  5. Shell case in语句详解

    和其它编程语言类似,Shell 也支持两种分支结构(选择结构),分别是 if else 语句和 case in 语句.在<Shell if else>一节中我们讲解了 if else 语句 ...

  6. ASCII 对应表

    { Bin (二进制) Oct (八进制) Dec (十进制) Hex (十六进制) 缩写/字符 解释 0000 0000 00 0 0x00 NUL(null) 空字符 0000 0001 01 1 ...

  7. Java——package和import关键字

    1.8 package和import关键字 1.8.1 package 包其实就是目录,特别是项目比较大,java 文件特别多的情况下,我们应该分目录管理,在java 中称为分包管理,包名称通常采用小 ...

  8. 7.12模拟T2(套路容斥+多项式求逆)

    Description: \(n<=10,max(w)<=1e6\) 题解: 考虑暴力,相当于走多维格子图,不能走有些点. 套路就是设\(f[i]\)表示第一次走到i的方案数 \(f[i] ...

  9. bzoj1025题解

    [题意分析] 定义一个等价类为满足如下条件的一个极大的集合Q:∀t∈Q,k∈N+,若tk∈全集R,都成立tk∈Q. 给定n,记[1,n]∩N上所有排列置换的全集为R.求对于所有的等价类Q,card({ ...

  10. 移动端图片轮播效果:depth模式总结

    最近公司app改版首页增加了一处轮播图效果,但是跟普通的轮播效果不同,是类似于下图的样式,找了一些兼容移动端的插件以及jQuery源码,总结一下使用心得: 1:jquery源码:缺点是在手机端的滑动很 ...