MFC中CStdioFile::Read触发AfxThrowFileException的原因与处理
MFC CStdioFile::Read 异常相关问题解答
我在MFC应用中使用CStdioFile::Read接口时,查看MFC源码发现filetxt.cpp文件里的UINT CStdioFile::Read函数会在以下条件触发异常:
if ((nRead = (UINT)fread(lpBuf, sizeof(BYTE), nCount, m_pStream)) == 0 && !feof(m_pStream)) AfxThrowFileException(CFileException::genericException, _doserrno, m_strFileName);
已知调用CStdioFile::Read前已通过CStdioFile::Open确认文件已打开,且理解nRead == 0表示未读取到字节、feof(m_pStream)为false说明未到达文件末尾,现针对相关疑问解答如下:
1. 触发该异常的可能原因有哪些?
- 底层磁盘硬件故障,比如出现坏道、磁盘损坏
- 文件所在存储设备突然断开(如U盘被拔出、移动硬盘断电)
- 读取过程中文件权限被修改,当前进程失去读取权限
- 文件被其他进程加了独占锁,当前进程无法读取数据
- 网络共享文件的连接中断(如NFS/SMB服务异常、网络断开)
- 磁盘空间耗尽,无法完成读取操作
- 之前的I/O操作已导致文件流处于错误状态,未被处理
2. 该异常是否可能由文件权限、文件锁定或磁盘错误导致?
是的,这三类情况都可能触发该异常:
- 文件权限:即使打开时权限正常,读取过程中文件权限被修改为当前进程无读取权限,
fread会返回0且feof为false - 文件锁定:其他进程对文件施加独占锁后,当前进程读取时
fread失败,满足异常触发条件 - 磁盘错误:磁盘坏道、硬件故障导致无法读取数据,
fread返回0且未触发EOF标记
3. 是否存在fread读取失败但feof返回false的特定场景?
存在多种这类场景:
- 读取被其他进程独占锁定的文件:此时
fread无法获取数据,文件指针也未到末尾,feof返回false - 读取磁盘坏道区域的数据:硬件层面无法读取,
fread返回0,且不会触发EOF - 读取网络共享文件时网络突然中断:
fread无法完成读取,流状态不会标记为EOF - 读取过程中文件被其他进程删除:此时
fread返回0,文件流未触发EOF标记
4. 应如何正确处理该异常以区分不同的失败场景?
通过捕获CFileException异常,结合错误码和系统错误信息来区分场景,步骤如下:
- 捕获异常:用
try-catch块包裹CStdioFile::Read调用try { UINT bytesRead = file.Read(lpBuf, nCount); } catch (CFileException* pEx) { // 处理异常逻辑 pEx->Delete(); } - 获取错误详情:
- 通过
pEx->m_cause获取MFC定义的文件错误类型 - 通过
pEx->m_lOsError(对应_doserrno)获取系统级错误码,比如:- 权限问题:
ERROR_ACCESS_DENIED(错误码5) - 文件锁定/共享冲突:
ERROR_SHARING_VIOLATION(32)、ERROR_LOCK_VIOLATION(33) - 磁盘错误:
ERROR_READ_FAULT(30)、ERROR_DISK_FULL(112) - 网络错误:
ERROR_NETWORK_UNREACHABLE(1231)
- 权限问题:
- 调用
pEx->GetErrorMessage获取可读的错误描述
- 通过
- 针对性处理:根据错误码执行对应逻辑,比如权限问题提示用户检查文件权限,锁定问题提示关闭占用文件的进程,磁盘错误提示检查存储设备
内容的提问来源于stack exchange,提问作者A Akshatha
相关产品推荐
相关产品推荐

