CFile类提供了对文件进行打开,关闭,读写,删除,重命名以及获取文件信息等文件操
作的基本功能,足以处理任意类型的文件操作。
CFile类是MFC文件类的基类,支持无缓冲的二进制输入输出,也可以通过与CArchive类
的配合使用而支持对MFC对象的带缓冲的序列化。
通过CFile类来打开文件可以采用两种方式:一种是先构造一个CFile类对象然后再调用
成员函数Open()打开文件,
另一种方法则直接使用CFile类的构造函数去打开一个文件。下面语句分别演示了用这两种
方法打开磁盘文件"C:\TestFile.txt"的过程。
1.先构造一个实例,然后再打开文件
CFile file;
int ret = file.Open("C:\\TestFile.txt", CFile::modeReadWrite);
// 报告文件打开是否成功
if (ret == TRUE)
AfxMessageBox("文件打开成功!");
else
AfxMessageBox("文件打开失败!");
2.直接通过构造函数打开文件
CFile file("C:\\TestFile.txt", CFile::modeReadWrite);
其中参数CFile::modeReadWrite是打开文件的模式标志,CFile类中与之类次的标志还有十
几个,先集中列如下表:
表1 文件模式标志
─────────────────────────────────────
文件模式标志 说明
─────────────────────────────────────
CFile::modeCreate 创建方式打开文件,如文件已存在则将其长度设置为0
─────────────────────────────────────
CFile::modeNoInherit 不允许继承
─────────────────────────────────────
CFile::modeNoTruncate 创建文件时如文件已存在不对其进行截断
─────────────────────────────────────
CFile::modeRead 只读方式打开文件
─────────────────────────────────────
CFile::modeReadWrite 读写方式打开文件
─────────────────────────────────────
CFile::modeWrite 写入方式打开文件
─────────────────────────────────────
CFile::shareCompat 在使用过程中允许其他进程同时打开文件
─────────────────────────────────────
CFile::shareDenyNone 在使用过程中允许其他进程对文件进行读写
─────────────────────────────────────
CFile::shareDenyRead 在使用过程中不允许其他进程对文件进行读写
─────────────────────────────────────
CFile::shareDenyWrite 在使用过程中不允许其他进程对文件进行写入
─────────────────────────────────────
CFile::shareExclusive 取消对其他进程的所有访问
─────────────────────────────────────
CFile::typeBinary 设置文件为二进制模式
─────────────────────────────────────
CFile::typeText 设置文件为文本模式
─────────────────────────────────────
这些标志可以通过“或”运算符而同时使用多个,并以此来满足多种需求。
如:
CFile file("C:\\TestFile.txt", CFile::modeWrite | CFile::modeCreate);
在打开的文件不再使用时需要将其关闭,既可以用成员函数Close()关闭也可以通过
CFile类的析构函数来完成。当采取后一种方式时,如果文件还没有被关闭,析构函数将
负责隐式调用Close()函数去关闭文件,这也表明创建在堆上的CFile类对象在超出范围
后将自动被关闭。由于调用了对象的析构函数,因此在文件被关闭的同时CFile对象也被
销毁,而采取Close()方式关闭文件后,CFile对象仍然存在。所以,在显式调用Close()
函数关闭一个文件后可以继续用同一个CFile对象去打开其他的文件。
文件读写是最常用的文件操作方式,主要由CFile类成员函数Read(),Write()来实现。
其函数原型分别为:
UINT Read(void* lpBuf,UINT nCount);
void Write(const void* lpbuf,UINT nCount);
参数lpBuf为指向存放数据的缓存的指针,nCount为要读入或写入的字节数,Read()返回
的为实际读取的字节数,该数值小于或等于nCount,如果小于nCount则说明已经读到文件
末尾,可以结束文件读取,如继续读取,将返回0。因此通常可以将实际读取字节数是否小
于指定读取的字节数或是否为0作为判断文件读取是否到达结尾的依据。下面这段代码演示
了对文件进行一次性写入和循环多次读取的处理过程。
// 缓存
char WriteBuf[1000];
char ReadBuf[100];
//创建、写入方式打开文件
CFile file;
file.Open("C:\\TestFile.txt", CFile::modeWrite | CFile::modeCreate);
// 写入文件
memset(WriteBuf, 'a', sizeof(WriteBuf));
file.Write(WriteBuf, sizeof(WriteBuf));
file.Close();
//只读方式打开文件
file.Open("C:\\TestFile.txt", CFile::modeRead);
while (true)
{
// 读取文件数据
int ret = file.Read(ReadBuf, 100);
……
// 如果到达文件结尾则中止循环
if (ret < 100)
break;
}//while
// 关闭文件
file.Close();
Write()和Read()函数执行完后将自动移动文件指针,因此不必再显式调用Seek()函数
去定位文件指针。包含有文件定位函数的完整代码如下所示:
char WriteBuf[1000];
char ReadBuf[100];
CFile file;
file.Open("C:\\TestFile.txt", CFile::modeWrite | CFile::modeCreate);
// 写入文件
memset(WriteBuf, 'a', sizeof(WriteBuf));
file.SeekToBegin();
file.Write(WriteBuf, sizeof(WriteBuf));
file.Close();
file.Open("C:\\TestFile.txt", CFile::modeRead);
while (true)
{
//文件指针
static int position=0;
//移动文件指针
file.Seek(position,CFile::begin);
// 读取文件数据
int ret = file.Read(ReadBuf, 100);
position+=ret;
……
// 如果到达文件结尾则中止循环
if (ret < 100)
break;
}//while
file.Close();