提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
转帖|使用教程|编辑:鲍佳佳|2021-06-28 10:27:52.563|阅读 161 次
概述:本节介绍下Visual c++/MFC界面开发中文件操作类CFile类的使用。Windows系统的API函数除了ReadFile,还有CreateFile、WriteFile等函数。而MFC基于面向对象的思想,将这些Windows API函数封装到了CFile类中,实现对文件的打开、关闭、读、写、获取文件信息等操作。使用CFile类对文件进行操作非常便捷。
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
相关链接:
上一节中讲了定时器Timer的用法,本节介绍下Visual c++/MFC界面开发中文件操作类CFile类的使用。在内容开始前为大家介绍两款MFC界面开发控件:
如果你学过C语言,应该知道文件操作使用的是文件指针,通过文件指针实现对它指向的文件的各种操作。这些文件操作函数中有的最终还是调用了操作系统的API函数或者处理过程与之类似,例如在Windows系统中,fread函数就调用了API函数ReadFile。
Windows系统的API函数除了ReadFile,还有CreateFile、WriteFile等函数。而MFC基于面向对象的思想,将这些Windows API函数封装到了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对象时就打开文件,然后向文件中写入数据,最后以Seek函数移动文件指针,读取文件内容。
C++代码
char writeBuffer[500]; // 要写入的数据的缓存 char readBuffer[500]; // 存放读取数据的缓存 LONGLONG lOff = 0; // 文件指针的偏移量,也是读取到的数据的总字节数 // 构造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, 100); // 根据实际读取的字节数,增加文件指针的移动量 lOff += nRet; // 如果读取数据时返回值小于指定的100,说明已到文件尾,跳出循环 if (nRet < 100) break; } // 关闭文件 file.Close();
实际上,在Write函数和Read函数执行后,文件指针会自动移动到最后操作的位置,所以其实上面的代码中无须使用Seek函数再去手动移动文件指针。这将在下面的实例二中体现出来。
实例二:构造CFile对象,然后使用Open成员函数打开文件,再写入一个结构体数组,最后读取出来。
先贴上结构体的定义:
C++代码
struct student { int nNum; float fScore; };
下面是文件操作的代码片段:
C++代码
student s1[2]; // 存放要写入文件的数据 student s2[2]; // 存放从文件读取的数据 CFile file; // CFile对象 int nReadBytes = 0; // 从文件中读取到的总字节数 // 为s1数组各元素赋值 s1[0].nNum = 22; s1[0].fScore = 91.5; s1[1].nNum = 23; s1[1].fScore = 85; // 以创建、读写方式打开文件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(); }
本节内容就到这里,如果有其他语言的文件操作的经验的话,应该还是比较简单的。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn
文章转载自:本文探讨 SQL Server 中 NULL 和空值之间的区别,并讨论如何有效地处理它们。
Unity 是一款功能极其丰富的游戏引擎,允许开发人员将各种媒体集成到他们的项目中。但是,它缺少最令人兴奋的功能之一 - 将 Web 内容(例如 HTML、CSS 和 JavaScript)直接渲染到 3D 场景中的纹理上的能力。在本文中,我们将介绍如何使用 DotNetBrowser 在 Unity3D 中将 Web 内容渲染为纹理。
DevExpress v24.2帮助文档正式发布上线了,请按版本按需下载~
本教程将向您展示如何用MyEclipse构建一个Web项目,欢迎下载最新版IDE体验!
用于构建类似微软Office、Visual Studio等MFC用户界面高级套包。
Xtreme Toolkit Pro专为Windows平台开发人员提供最全面的Visual C++界面开发组件
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@pclwef.cn
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢