打开文件时出现异常
Posted
技术标签:
【中文标题】打开文件时出现异常【英文标题】:Exception while opening file 【发布时间】:2010-03-24 09:24:07 【问题描述】:我有一个 VC++ 应用程序,在我的应用程序中我有一些基本的文件操作。
下面是默认代码
CStdioFile cFile;
CFileException e;
CString sReport;
CString shtmlfile = "testreport.html"
OutputDebugString((sHtmlfile));
if (!cFile.Open(sHtmlfile,CFile::modeCreate | CFile::modeWrite, &e ))
问题是我的应用程序每隔几分钟就会执行一次这段代码。而且效果很好。
在多次运行代码后,cFile.Open() 函数失败。我试图得到错误信息
TCHAR szError[1024];
e.GetErrorMessage(szError,1024);
OutputDebugString((szError));
具有讽刺意味的是 szError 错误消息是“没有发生错误”。
一旦我重新启动我的应用程序,这将再次起作用。知道为什么会这样。
提前致谢。
【问题讨论】:
请缩进您的代码以便格式化。 (只需标记并单击代码按钮)。 这段代码让我想起了为什么我讨厌 MFC。 我的第一个猜测是,在某些情况下,文件没有被关闭。但是,既然您似乎确定它正在被关闭,那么还有哪些其他进程正在使用该文件?网络浏览器?在您尝试打开文件时,是否还有其他东西正在读取文件(并使用shareDenyWrite
或类似模式打开)?
【参考方案1】:
您是否有多个实例正在运行?我建议你在错误发生时使用Process Explorer,看看是否存在该文件的任何其他句柄。
而GetLastError
会报上一个API函数报错。如果在失败的 API 调用和对 GetLastError
的调用之间存在任何其他 API 调用,则最后一个错误值将被覆盖。 (正如@sbi 在 cmets 中已经指出的那样。)
【讨论】:
不,我没有运行多个实例。让我看看我是否可以使用流程资源管理器。是的,但我不调用任何其他 API,因此最后一个错误值无法覆盖。可以参考上面的代码。CStdioFile::Open
类中可能还有其他 API 调用。 'CStdioFile' 的源代码与 MFC 一起提供...可能有助于查看(尽管经验另有说明)。
文件成功打开后,您具体如何处理?
一旦我打开文件,我会在其中填充许多包含一些数据报告之类的内容,然后我将文件邮寄到几个电子邮件地址。最后当然是我关闭了文件。
搜索testreport.html
。这应该为您提供该文件的所有打开文件句柄的列表。此外,列出打开文件的进程的名称和 PID。【参考方案2】:
Maube 您忘记关闭文件并且它来自文件描述符。当您退出应用程序时,它们都已关闭,然后您可以再次运行它。检查您的文件是否已关闭。
好的。如果不是上述情况,那可能是什么?您从 cFile.Open 收到错误消息,因此我们可以相信它是准确的。
我不确定如果当前进程已经打开了另一个同名文件,或者如果您尝试打开一个名称奇怪的文件,例如空字符串,会发生什么。要解决这些问题,您还可以打印您正在打开的错误文件的名称(并跟踪未发生错误的情况)。
【讨论】:
CFile.Close 在这个函数结束时被调用。所以这一定不是问题 @viswanathan:这仅在cFile.Close()
实际执行时才成立。如果您必须手动执行此操作,则异常很可能会阻止它执行。 (据我们所知,或者早期的return
。我们还没有看到你的代码。)这就是 RAII 的用途。
可以放心,CFile.Close() 实际执行。在此之前没有返回语句。我已经通过单步执行代码验证了这一点。
@viswanathan:我学到了一种艰难的方法,除非得到证实,否则不要假设任何事情。当打开失败时,您是否使用某些可用工具检查文件是否已经打开? (它叫什么名字?FileMonitor?)
@viswanathan:请注意,“未发生错误”消息本身也可能是错误。这听起来像GetLastError()
报告的内容。如果库代码在失败的 API 和调用 GetLastError()
之间调用任何其他 API,则该消息具有误导性。【参考方案3】:
您正在使用 C++。您的错误可能完全在其他地方。我遇到了一个指针错误,导致干净的代码出现错误。
您是否尝试过在发布模式下构建?
我建议尝试逐步检查并缩小出现错误的范围。
【讨论】:
我已经单步执行了代码,我发现它在 CFile::Open() 中完全失败了。当我在发布版本中运行相同的内容时,我也可以以相同的结果重现该问题。我还应该尝试什么? 尝试添加 NULL 作为 Open() 的第三个参数,并在捕获 CFileException 的 try/catch 部分中包围函数调用。我从文档中假设这一点,“虽然 CFile 构造函数将在错误条件下抛出异常,但 Open 将在错误条件下返回 FALSE。”我还看到您很可能从 Open docs 复制了该示例。明确的区别是它们使用 char* 而您使用的是 CString。您确定 CString 正确地转换为 LPCTSTR 吗? 另一个与我之前的帖子有关的建议是...检查您的 CString 的地址空间是否在某些时候没有被覆盖。这表明您的错误与野指针有关。 好吧,我刚刚发现创建的文件大小为 0KB,但我无法使用它们,因为异常仍然发生。这可能是一个手柄问题 如果是这种情况,那么我的第一个猜测是 'CFile::modeWrite' 失败了。 close() 发生的速度是否不够快,以至于出现争用错误?也许在文件名中添加一个计数器,看看错误是否仍然存在。因此,您的文件将是 testreport1.html、testreport2.html 等......为什么您仍然快速打开和关闭文件?如果你一遍又一遍地写入同一个文件,那么为什么不使用一个实例变量来保存打开的文件并在你完全完成后关闭它呢?以上是关于打开文件时出现异常的主要内容,如果未能解决你的问题,请参考以下文章
尝试将docker容器连接到mongodb时出现异常打开套接字异常
尝试使用Microsoft.Office.Interop.Excel.Workbooks.Open()打开Excel时出现异常HResult 0x800a03ec