MFC-文件操作CFile
文本文件的读写
CFile mfile;//创建文件对象 BOOL b= mfile.Open(_T("D:\\测试.txt"), CFile::modeCreate| CFile::modeNoTruncate,NULL);//打开文件 /* 参数1:LPCTSTR 包含所需文件的路径的字符串。 该路径可以是相对路径、绝对路径或网络名称 (UNC) 参数2:UINT 用于定义文件的共享和访问模式的 UINT。 它指定打开文件时要执行的操作。 可以使用按位“或”(|) 运算符来组合选项 文件访问模式: CFile::modeRead 默认-只读 CFile::modeWrite 只写 CFile::modeReadWrite 读写 字符模式: CFile::typeBinary 设置二元模式(仅在派生类中使用) CFile::typeText 通过对回车符-换行符对进行特殊处理,来设置文本模式(仅在派生类中使用) CFile::typeUnicode 设置 Unicode 模式(仅在派生类中使用)。 当应用程序在 Unicode 配置中生成时, 文本将以 Unicode 格式写入文件中。 不会将 BOM 写入该文件中 文件共享模式: CFile::shareDenyNone 没有任何共享限制 CFile::shareDenyRead 拒绝向所有其他用户提供读取访问权限 CFile::shareDenyWrite 拒绝向所有其他用户提供写入访问权限 CFile::shareExclusive 默认-拒绝向所有其他用户提供读写访问权限 文件创建模式: CFile::modeCreate 如果文件不存在,则创建一个新文件。 如果文件已存在,则将其覆盖并初始设置为零长度【清空】 CFile::modeNoTruncate 追加方式打开;如果文件不存在,会抛出异常;如果文件已存在,打开并且不清空 这两个模式可以一起使用:如果文件不存在,则创建一个新文件;如果文件已存在,打开并且不清空 文件缓存选项:默认情况下,系统将使用通用的缓存方案,该方案不可用作选项 CFile::osNoBuffer 系统没有为文件使用中间缓存。 此选项取消以下 2 个选项。 CFile::osRandomAccess 文件缓存针对随机访问进行了优化。 不要同时使用此选项和顺序扫描选项。 CFile::osSequentialScan 文件缓存针对顺序访问进行了优化。 不要同时使用此选项和随机访问选项。 CFile::osWriteThrough 写入操作将无延迟地完成 选择下列安全选项以防止继承文件句柄。 默认情况下,所有新的子进程都可以使用文件句柄 CFile::modeNoInherit 阻止任何子进程使用文件句柄 参数3:CFileException* pError = NULL 指向接收失败操作状态的现有文件异常对象的指针 返回值:如果成功打开,则返回非零值;否则返回 0。 仅当返回 0 时,pError 参数才有意义 */ mfile.Close();//关闭文件
CFile mfile;//创建文件对象 BOOL b= mfile.Open(_T("D:\\测试.txt"), CFile::modeCreate| CFile::modeNoTruncate| CFile::modeReadWrite,NULL);//打开文件 TCHAR szbuf[100] = { 0 }; UINT n=mfile.Read(szbuf,sizeof(szbuf)-sizeof(TCHAR));//读取文件指针后的内容 /* 参数1:void* lpBuf 指向用户提供的缓冲区的指针,该缓冲区接收从文件中读取的数据 参数2:UINT nCount 要从文件中读取的最大字节数。 对于文本模式文件,回车符-换行符对算作一个字符 返回值:传输到缓冲区的字节数。 对于所有 CFile 类,如果已到达文件末尾,则返回值可能小于 nCount */ /*注意:读取内容后,szbuf如果是乱码,说明文件编码不是Unicode, 方法一:修改文件编码 方法二:用下面的MultiByteToWideChar转换 */ int nLen = _tcslen(szbuf); // 获取ANSI字符串的长度 int nWLen = MultiByteToWideChar(CP_ACP, NULL, (char*)szbuf,-1 , NULL, 0); //计算转换为 Unicode 字符串所需的缓冲区大小 /* 说明:szbuf是TCHAR,所以用char*强转 */ WCHAR* wszUnicodeBuf = new WCHAR[nWLen+1]; // 分配用于存储 Unicode 字符串的缓冲区 MultiByteToWideChar(CP_ACP, NULL, (char*)szbuf, -1, wszUnicodeBuf, nWLen); // 进行实际的 ANSI 到 Unicode 的转换,并将结果存储在 wszUnicodeBuf 中 mfile.Close();//关闭文件
CFile mfile;//创建文件对象 BOOL b= mfile.Open(_T("D:\\测试.txt"), CFile::modeCreate| CFile::modeNoTruncate| CFile::modeReadWrite,NULL);//打开文件 TCHAR szbuf[100] = { 0 }; UINT n=mfile.Read(szbuf,sizeof(szbuf)-sizeof(TCHAR));//读取文件的内容 TCHAR tc[] = _T("MFC学习"); mfile.Write(tc,sizeof(tc)-1);//将缓冲区中的数据写入文件 /* 参数1:const void* lpBuf 指向用户提供的缓冲区的指针 参数2:UINT nCount 要写入的字节数;对于文本模式文件,回车符-换行符对算作一个字符 注意:只有close和Flush时才真正写入文件 说明:-1是减去字符串末尾的\0 */ mfile.Close();//关闭文件
CStdioFile mfile;//创建文件对象 //CStdioFile是CFile的子类 BOOL b= mfile.Open(_T("D:\\测试.txt"), CFile::modeCreate| CFile::modeNoTruncate| CFile::modeReadWrite| CFile::typeUnicode,NULL);//打开文件 if (!b) { AfxMessageBox(_T("文件打开失败")); return; } CString str; bool b1=mfile.ReadString(str);//读取一行文本 /* 参数1:CString& rString 对 CString 对象的引用,该对象将在函数返回时包含字符串 返回值:在没有读取任何数据的情况下到达文件尾,则为 FALSE 包含\r,读完之后移动文件指针 注意:CStdioFile::ReadString()函数默认将文本文件视为ANSI编码进行读取 如果是Unicode就加上CFile::typeUnicode */ b1 = mfile.ReadString(str);//读取一行文本 if (!b) { AfxMessageBox(_T("读取失败")); return; } ULONGLONG nu= mfile.SeekToEnd();//将文件指针移到文件末尾 /* 返回值:文件的长度(以字节为单位) */ mfile.WriteString(_T("888\r\n"));//写入一行 /* 参数:LPCTSTR lpsz 指定指向包含以 null 结尾的字符串的缓冲区的指针 终止空字符 (\0) 不会写入文件。 此方法会将 lpsz 中的换行符作为回车-换行符对写入文件中 不会添加换行,需要换行加上\r\n 如果文件指针不在末尾:是覆盖,不是插入 注意:如果文件指针位置不正确,会写入失败,写入前用SeekToEnd等函数确定文件指针 */ mfile.WriteString(_T("999")); mfile.Close();//关闭文件
CStdioFile mfile; // 创建文件对象 BOOL b = mfile.Open(_T("D:\\测试.txt"), CFile::modeNoTruncate|CFile::modeCreate | CFile::modeReadWrite | CFile::typeUnicode, NULL); // 打开文件 if (!b) { AfxMessageBox(_T("文件打开失败")); return; } //ULONGLONG n1=mfile.SeekToEnd();//文件指针移到末尾 //返回值:文件的长度(以字节为单位) //mfile.SeekToBegin();//文件指针移到0位置 ULONGLONG n = mfile.Seek(5 * sizeof(TCHAR), CFile::begin);//定位文件指针 /* 打开文件时,文件指针将定位在 0 位置,即文件的开头 参数1:LONGLONG lOff 要将文件指针移动的字节数 如果使用正值,则将文件指针移向文件的末尾;如果使用负值,则将文件指针移向文件的开头 参数2:UINT nFrom 要在其中进行查找的位置 CFile::begin 从文件的开头查找 CFile::current 从文件指针的当前位置查找 CFile::end 从文件的末尾查找 返回值:如果该方法成功,则返回文件指针的位置; 否则返回未定义的值,以及指向引发的 CFileException 异常的指针 【实际移动了(n-1)* sizeof(TCHAR)】 不知道为何,请知道的告诉我 */ TCHAR tc[] = _T("MFC学习"); mfile.Write(tc, sizeof(tc) - 2);//将缓冲区中的数据写入文件 mfile.Close(); // 关闭文件
CStdioFile mfile; // 创建文件对象 BOOL b = mfile.Open(_T("D:\\测试.txt"), CFile::modeNoTruncate|CFile::modeCreate | CFile::modeReadWrite | CFile::typeUnicode, NULL); // 打开文件 if (!b) { AfxMessageBox(_T("文件打开失败")); return; } ULONGLONG n = mfile.Seek(5 * sizeof(TCHAR), CFile::begin);//定位文件指针 TCHAR tc[] = _T("MFC学习"); mfile.Write(tc, sizeof(tc) - 2);//将缓冲区中的数据写入文件 mfile.Flush();//把缓冲区的内容写入文件 mfile.Close(); // 关闭文件
文件的操作
MFC 中的 CFile 及其派生类中没有提供直接进行文件的复制操作,因而要借助于SDK API;
SDK中的文件相关函数常用的有CopyFile()、CreateDirectory()、DeleteFile()、MoveFile()
文件复制
BOOL b= CopyFile(_T("D:\\测试.txt"), _T("E:\\测试.txt"), FALSE);//文件复制 /* 参数1:LPCTSTR lpExistingFileName 文件路径 参数2:LPCTSTR lpNewFileName 目标路径 参数 3:BOOL bFailIfExists 如果此参数为 TRUE 并且 lpNewFileName 指定的新文件已存在,则函数将失败。 如果此参数为 FALSE 且新文件已存在,则函数将覆盖现有文件并成功 返回值:BOOL,非零表示成功,零表示失败。会设置GetLastError */
重命名文件和文件夹
CFile::Rename(_T("D:\\测试.txt"), _T("D:\\测试1.txt"));//重命名文件 /* 参数1:旧路径 参数2:LPCTSTR lpszNewName 新路径 参数3:CAtlTransactionManager* pTM = NULL 无法重命名目录 */
MoveFile(_T("D:\\aa"), _T("D:\\bbb"));//重命名文件夹
CFile::Rename(_T("D:\\bbb"), _T("D:\\aa"));//重命名文件夹
移动文件
BOOL b= MoveFile(_T("D:\\测试1.txt"), _T("E:\\测试1.txt"));//移动文件 /* 参数1:LPCTSTR lpExistingFileName 一个存在的文件或者文件夹字符串指针 参数2:LPCTSTR lpNewFileName 一个还没存在的文件或者文件夹的字符串指针 返回值:如果成功调用 返回非0 失败 返回0 */
删除文件
CFile::Remove(_T("D:\\zzzz.txt"));//删除文件 /* 参数:LPCTSTR lpszFileName 一个字符串,即所需文件的路径。 该路径可以是相对或绝对路径,并可以包含网络名称 Remove 不会删除目录 */
BOOL b=DeleteFile(_T("D:\\zzzz.txt"));//删除文件 /* 参数:LPCTSTR lpszFileName 一个字符串,即所需文件的路径。 返回值:成功返回非零,失败返回0 更多错误信息使用GetLastError获取 如果程序尝试删除一个不存在的文件。GetLastError返回ERROR_FILE_NOT_FOUND。 如果文件是只读 的,则GetLastError返回ERROR_ACCESS_DENIED */
获取文件信息
CFileStatus rStatus; BOOL b= CFile::GetStatus(_T("D:\\zz.txt"),rStatus);//获取文件信息 /* 参数1:LPCTSTR lpszFileName 文件的路径。 该路径可以是相对或绝对路径,也可以包含网络路径名称 参数2:CFileStatus& rStatus 接收状态信息的、用户提供的 CFileStatus 结构的引用。 CFileStatus 结构包含以下字段: CTime m_ctime 文件的创建日期和时间。 CTime m_mtime 文件的上次修改日期和时间。 CTime m_atime 上次对文件进行读取访问的日期和时间。 ULONGLONG m_size DIR命令报告的文件逻辑大小(以字节为单位)。 BYTE m_attribute 文件的属性字节 normal = 0x00 readOnly = 0x01 //只读 hidden = 0x02 //隐藏 system = 0x04 //系统 volume = 0x08 directory = 0x10 archive = 0x20 //存档 char m_szFullName[_MAX_PATH] Windows 字符集中的绝对文件名 */
DWORD d= GetFileAttributes(_T("D:\\zz.txt")); /* 参数:LPCTSTR lpFileName 指定的文件或目录名称 对于ANSI版本,名字不能大于MAX_PATH 返回值:如果函数失败,返回值是INVALID_FILE_ATTRIBUTES GetLastError() == ERROR_FILE_NOT_FOUND 文件没找到 GetLastError() == ERROR_PATH_NOT_FOUND 文件夹没找到 如果函数成功后返回以下值中的一个或多个 FILE_ATTRIBUTE_ARCHIVE 标示一个文件(或目录)是一个存档文件(或目录) FILE_ATTRIBUTE_COMPRESSED 标示一个文件(或目录)是一个压缩文件(或目录) 用于文件时:该文件中所有的记录都是经过压缩的; 用于目录时:在该目录下新建文件或子目录时会默认进行压缩。 FILE_ATTRIBUTE_DEVICE 未使用 FILE_ATTRIBUTE_DIRECTORY 此句柄被视为一个目录 FILE_ATTRIBUTE_ENCRYPTED 标示一个文件(或目录)是一个加密文件(或目录) 用于文件时:该文件中所有的记录都是经过加密的,包括读写操作; 用于目录时:在该目录下新建文件或子目录时会默认进行加密 FILE_ATTRIBUTE_HIDDEN 标示一个文件(或目录)是一个隐藏文件(或目录) FILE_ATTRIBUTE_NORMAL 标示一个文件(或目录)不具有其他属性,此属性只能单独使用 FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 标示一个文件不可被内容索引服务索引 FILE_ATTRIBUTE_OFFLINE 标示一个文件是脱机文件,该文件中的内容无法直接使用 如果某个文件具有该属性,请不要轻易修改此属性,它可能是某些远程存储服务程序的存储文件。 FILE_ATTRIBUTE_READONLY 标示一个文件(或目录)是一个只读文件(或目录) 用于文件时:只能读取文件内容,无法修改或删除; 用于目录时:该目录无法删除。 FILE_ATTRIBUTE_REPARSE_POINT 标示一个文件(或目录)拥有相关的重新解析点,比如用mklink创建的硬链接(hardLink)或符号链接(symbolic link) FILE_ATTRIBUTE_SPARSE_FILE 标示一个文件是稀疏文件。 FILE_ATTRIBUTE_SYSTEM 标示一个文件(或目录)是一个系统文件(或目录) FILE_ATTRIBUTE_TEMPORARY 标示一个文件是临时文件 FILE_ATTRIBUTE_VIRTUAL 标示一个文件是系统文件。 */ if (d== INVALID_FILE_ATTRIBUTES) { AfxMessageBox(_T("失败")); } if (d & FILE_ATTRIBUTE_ARCHIVE) { //通过&来判断属性 AfxMessageBox(_T("存档文件")); }
/* typedef struct _WIN32_FILE_ATTRIBUTE_DATA { DWORD dwFileAttributes;//判断一个目标为文件夹还是文档, //目标为文档是dwFileAttributes的值为FILE_ATTRIBUTE_ARCHIVE(32), //而为文件夹时值为FILE_ATTRIBUTE_DIRECTORY(16) FILETIME ftCreationTime; //创建时间 FILETIME ftLastAccessTime;//修改时间 FILETIME ftLastWriteTime;//访问时间 DWORD nFileSizeHigh; //文件的大小,分高位和低位 DWORD nFileSizeLow; } WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA; */ WIN32_FILE_ATTRIBUTE_DATA wafd; BOOL b=GetFileAttributesEx(_T("D:\\zz.txt"), GetFileExInfoStandard, &wafd);//获取文件信息 /* 获取文件或目录的属性、时间、大小,以WIN32_FILE ATTRIBUTE_DATA结构的形式返回结果 参数1:文件或目录 参数2:是获取文件属性信息的类别,会影响到参数3具体采用什么形式输出结果。 但是本参数一般只能指定为GetFileExInfoStandard 参数3:LPWIN32_FILE_ATTRIBUTE_ DATA类型 返回值:如果函数成功,则返回值为非零值 如果函数失败,则返回值为零 (0) 。 要获得更多的错误信息,请调用 GetLastError */
设置文件信息
CFileStatus rStatus; rStatus.m_attribute= CFile::archive; CFile::SetStatus(_T("D:\\zz.txt"), rStatus);//设置文件信息 /* 参数1:LPCTSTR lpszFileName 一个字符串,即所需文件的路径。 该路径可以是相对或绝对路径,并可以包含网络名称 参数2:const CFileStatus & status */
判断文件是否存在
BOOL TargetIsExist(LPCTSTR lpszPath) //判断文件是否存在 /* 参数:路径 返回FALSE,表示文件不存在 返回TRUE,表示文件存在 */ { BOOL bRet = TRUE; DWORD dwRet = GetFileAttributes(lpszPath); if (dwRet == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND) { bRet = FALSE; } return bRet; }
判断给定路径是文件还是目录
int TargetIsDirectory(LPCTSTR lpszPath) //判断给定路径是文件还是目录 /* 参数:路径 返回-1,表示失败 返回1,表示目录 返回0,表示文件 */ { int iRet = -1; DWORD dwRet = GetFileAttributes(lpszPath); if (dwRet == INVALID_FILE_ATTRIBUTES) { iRet = -1; } else if (dwRet & FILE_ATTRIBUTE_DIRECTORY) { iRet = 1; } else { iRet = 0; } return iRet; }
文件夹的基本操作
BOOL b=CreateDirectory(_T("D:\\z"), NULL);//创建文件夹 /* 参数1:LPCTSTRlpPathName 文件夹名称 参数2:LPSECURITY_ATTRIBUTES lpSecurityAttributes 为安全属性,一般设置为NULL即可 返回值:如果正确创建,返回值为1,如果没有正常创建文件夹,则返回0;会设置GetLastError 该函数每次调用时都只能创建一级文件夹,即文件夹中不能再包含子文件夹 */ BOOL b1= RemoveDirectory(_T("D:\\z"));//删除文件夹 /* 参数1:LPCTSTRlpPathName 文件夹名称 返回值:非零表示成功,零表示失败。可以调用GetLastError获得错误信息 目录必须为空 */
文件夹属性信息的获取:GetFileAttributes 看上面
遍历文件夹
//示例代码,实现删除非空目录 /* 文件和文件夹的遍历操作 MFC 中对文件的遍历操作所支持的类是:CFileFind */ BOOL DeleteTargetFolder(LPCTSTR lpstrPath) //参数:文件夹路径 { CString strRootPath(lpstrPath);//路径转换成CString if (strRootPath[strRootPath.GetLength() - 1] != '\\') strRootPath = strRootPath + _T("\\"); CFileFind mFinder;//构造 CFileFind 对象 BOOL bFind = mFinder.FindFile(strRootPath + _T("*.*"), 0); //寻找指定文件 //如果指定文件类型的话,只能在本目录中遍历 /* 参数1:LPCTSTR pstrName = NULL 一个指针,指向包含要查找文件的名称的字符串。 如果为 pstrName 传递 NULL,则 FindFile 将执行通配符 (*.*) 搜索 参数2:DWORD dwUnused = 0 预留用于使用派生类实现 FindFile 多态。 必须为 0 返回值:如果成功,则不为 0;否则为 0。 若要获得扩展的错误信息,请调用 Win32 函数 GetLastError */ while (bFind) { bFind = mFinder.FindNextFile();//寻找下一个文件 /* 继续从上一次对 FindFile 的调用继续文件搜索 返回值:如果有更多文件,则为非零; 如果找到的文件是目录中的最后一个文件或发生错误,则为零。 若要获得扩展的错误信息,请调用 Win32 函数 GetLastError。 如果找到的文件是目录中的最后一个文件,或者找不到匹配的文件,GetLastError 函数便返回 ERROR_NO_MORE_FILES */ if (mFinder.IsDots()) { /* FindNextFile函数找到的文件是不是“.”或“..” 返回值:如果所找到文件的名称为“.”或“..”,则为非零,表示所找到文件实际上是目录。 否则为 0 在调用 IsDots 前,必须至少调用一次 FindNextFile */ continue;//结束本次循环 } else { if (mFinder.IsDirectory()) { //找到的文件是目录 DeleteTargetFolder(mFinder.GetFilePath()); } else { //目标是文件 DeleteFile(mFinder.GetFilePath()); } } } mFinder.Close(); RemoveDirectory(strRootPath); //一定要放在 mFinder.Close(); 的下面,否则删除失败,提示文件夹正被使用中 return TRUE; }
CFileFind
看:https://learn.microsoft.com/zh-cn/cpp/mfc/reference/cfilefind-class?view=msvc-170
CFile异常处理
try { CFile::Remove(_T("D:\\qq.txt")); } catch (CFileException* pEx) { AfxMessageBox(_T("文件不能被删除")); pEx->Delete(); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2019-07-27 pyqt5-QTDesigner--控件操作