MFC读写⽂件详解
1.CFile类提供了对⽂件进⾏打开,关闭,读,写,删除,重命名以及获取⽂件信息等⽂件操作的基本功能,⾜以处理任意类型的⽂件操作。
虽然使⽤CArchive类内建的序列化功能是保存和加载持久性数据的便捷⽅式,但有时在程序中需要对⽂件处理过程拥有更多的控制权,对于这种⽂件输⼊输出(I/O)服务
的需求,Windows提供了⼀系列相关的API函数,并由将其封装为CFile类,提供了对⽂件进⾏打开,关闭,读,写,删除,重命名以及获取⽂件信息等⽂件操作的基本功
能,⾜以处理任意类型的⽂件操作。CFile类是MFC⽂件类的基类,⽀持⽆缓冲的⼆进制输⼊输出,也可以通过与CArchive类的配合使⽤⽽⽀持对MFC对象的带缓冲的序列化。
CFile类包含有⼀个公有型数据成员m_hFile,该数据成员包含了同CFile类对象相关联的⽂件句柄。如果没有指定句柄,则该值为CFile::hFileNull。由于该数据成员所包含的
意义取决于派⽣的类,因此⼀般并不建议使⽤m_hFile。
通过CFile类来打开⽂件可以采取两种⽅式:⼀种⽅式是先构造⼀个CFile类对象然后再调⽤成员函数Open()打开⽂件,另⼀种⽅式则直接使⽤CFile类的构造函数去打开
⼀个⽂件。下⾯的语句分别演⽰了⽤这两种⽅法打开磁盘⽂件“C:/1.txt”的过程:
CFile file;
file.open("C://1.txt",CFile::modeReadWrite);
其中参数CFile::modeReadWrite是打开⽂件的模式标志,CFile类中与之类似的标志还有⼗⼏个,现集中列表如下:
⽂件模式标志说明
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 设置⽂件为⽂本模式
这些标志可以通过“或”运算符⽽同时使⽤多个,并以此来满⾜多种需求。例如,需要以读写⽅式打开⽂件,如果⽂件不存在就创建⼀个新的,如果⽂件已经存在则不将其⽂
件长度截断为0。为满⾜此条件,可⽤CFile::modeCreate、CFile::modeReadWrite和CFile::modeNoTruncate等⼏种⽂件模式标志来打开⽂件:
CFile file("C://1.txt",CFile::modeCreate|CFile::modeReadWrite|CFile::modeNoTruncate);
在打开的⽂件不再使⽤时需要将其关闭,即可以⽤成员函数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作为判断⽂件读取是否到达结尾的依据。下⾯这
段代码演⽰了对⽂件进⾏⼀次性写⼊和循环多次读取的处理过程:
CFile file;
file.Open("C://", CFile::modeWrite | CFile::modeCreate);
memset(WriteBuf, 'a', sizeof(WriteBuf));
file.Write(WriteBuf, sizeof(WriteBuf));
file.Close();
file.Open("C://", CFile::modeRead);
while (true)
{
int ret = file.Read(ReadBuf, 100);
if (ret < 100)
break;
}
file.Close();
Write()和Read()函数执⾏完后将⾃动移动⽂件指针,因此不必再显⽰调⽤Seek()函数去定位⽂件指针。包含有⽂件定位函数的完整代码如下所⽰:
CFile file;
file.Open("C://", CFile::modeWrite | CFile::modeCreate);
memset(WriteBuf, 'a', sizeof(WriteBuf));
file.SeekToBegin();
file.Write(WriteBuf, sizeof(WriteBuf));
file.Close();
file.Open("C://", 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;
}
file.Close();
2.有了读写⽂件的功能实际操作起来就简单起来,相当于数据库使⽤。
3.CFileFind类的使⽤
3.1开始查(指定查的⽬录)
CFileFind::FindFile(strFileName,0); //strName为要查的⽂件名,为NULL表⽰查“*.*”成功返回⾮0,失败返回0
3.2查下⼀个(获取当前⽂件信息,返回下⼀个⽂件是否存在)
CFileFind::FindNextFile(); //返回⾮0表⽰还有符合条件的下⼀个⽂件,返回0表⽰已是最后⼀个⽂件
3.3获取/判断⽂件信息
CFileFind::GetCreationTime(); //获取⽂件的创建时间,成功返回⾮0,失败返回0
virtual BOOL GetCreationTime(FILETIME *pFileTime) const; //FILETIME *:容纳时间的结构指针
virtual BOOL GetCreationTime(CTime& refTime) const; //CTime&:容纳时间的对象地址
FILETIME和CTime的相互转换:
FILETIME转CTime:
1、CTime对象在初始化时可以传递FILETIME结构
FILETIME ft;
CTime time(ft);
2、将FILETIME转换为SYSTEMTIME,然后CTime对象在初始化时可以传递SYSTEMTIME结构
FILETIME ft;
SYSTEMTIME st;
BOOL bSuccess=::FileTimeToSystemTime(&ft , &st);
CTime time(st);
CTime转FILETIME:
CTime time(CTime::GetCurrentTime());
SYSTEMTIME st;
time.GetAsSystemTime(st);
truncate读 FILETIME ft;
::SystemTimeToFileTime(&st,&ft);
CFileFind::GetLastAccessTime(); //获取⽂件最后被访问的时间,成功返回⾮0,失败返回0
virtual BOOL GetLastAccessTime(FILETIME *pFileTime) const;
virtual BOOL GetLastAccessTime(CTime& refTime) const;
CFileFind::GetLastWriteTime(); //获取⽂件最后被修改的时间,成功返回⾮0,失败返回0
virtual BOOL GetLastWriteTime(FILETIME *pFileTime) const;
virtual BOOL GetLastWriteTime(CTime& refTime) const;
CFileFind::GetRoot(); //获取查到的⽂件的根⽬录,必须在执⾏FindNextFile()后执⾏该函数,返回CString对象
CFileFind::GetFileName(); //获取查到的⽂件的全名(包含扩展名),必须在执⾏FindNextFile()后执⾏该函数,返回CString对象
CFileFind::GetFilePath(); //获取查到的⽂件的绝对路径,必须在执⾏FindNextFile()后执⾏该函数,返回CString对象
CFileFind::GetFileTitle(); //获取查到的⽂件的名称(若系统默认隐藏⽂件扩展名则不显⽰),必须在执⾏FindNextFile()后执⾏该函数,返回CString对象
CFileFind::GetFileURL(); //获取查到的⽂件的URL路径,必须在执⾏FindNextFile()后执⾏该函数,返回CString对象
CFileFind::GetLength(); //获取查到的⽂件的长度DWORD
CFileFind::IsArchived(); //判断查的⽂件属性是否是档案⽂件,必须在执⾏FindNextFile()后执⾏该函数,⾮0表⽰是,0表⽰不是 CFileFind::IsCompressed(); //判断查的⽂件属性是否是压缩⽂件,必须在执⾏FindNextFile()后执⾏该函数
CFileFind::IsDirectory(); //判断查的⽂件属性是否为路径⽂件(⽂件夹),必须在执⾏FindNextFile()后执⾏该函数
CFileFind::IsDots(); //判断查的⽂件属性是否是“.”、“..”,必须在执⾏FindNextFile()后执⾏该函数
CFileFind::IsHidden(); //判断查的⽂件属性是否为隐藏⽂件,必须在执⾏FindNextFile()后执⾏该函数
CFileFind::IsNormal(); //判断查的⽂件属性是否为正常⽂件,必须在执⾏FindNextFile()后执⾏该函数
CFileFind::IsReadOnly(); //判断查的⽂件属性是否为只读⽂件,必须在执⾏FindNextFile()后执⾏该函数
CFileFind::IsSystem(); //判断查的⽂件属性是否为系统⽂件,必须在执⾏FindNextFile()后执⾏该函数
CFileFind::IsTemporary(); //判断查的⽂件属性是否为临时⽂件,必须在执⾏FindNextFile()后执⾏该函数
CFileFind::MatchesMask(DWORD dwMask); //判断查的⽂件的综合属性,必须在执⾏FindNextFile()后执⾏该函数
dwMask参数包括:
FILE_ATTRIBUTE_ARCHIVE:档案⽂件
FILE_ATTRIBUTE_COMPRESSED:压缩⽂件
FILE_ATTRIBUTE_DIRECTORY:路径⽂件
FILE_ATTRIBUTE_NORMAL:正常⽂件
FILE_ATTRIBUTE_READONLY:只读⽂件
FILE_ATTRIBUTE_SYSTEM:系统⽂件
FILE_ATTRIBUTE_TEMPORARY:临时⽂件
FILE_ATTRIBUTE_HIDDEN:隐藏⽂件
3.4结束查
CFileFind::Close();
4.结束疲倦的⼀天,明天继续美好的⽣活。
改变⾃⼰,从现在做起-----------久馆
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论