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();
    }
复制代码

 

 

 

 

 

 

posted @   天子骄龙  阅读(1293)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2019-07-27 pyqt5-QTDesigner--控件操作
点击右上角即可分享
微信分享提示

目录导航