为什么在C语言中需要关闭文件?

3
假设我们在C语言中使用fopen()打开了一个文件,但是不小心忘记使用fclose()关闭它,这会有什么后果?如果我们没有源代码,只有可执行文件,该怎么办呢?
如果没有关闭文件,可能会导致内存泄漏和资源浪费。在某些情况下,操作系统可能会强制关闭文件,但这并不总是发生。
如果我们只有可执行文件,可以考虑使用工具来检测文件句柄泄漏,例如FileMon或Process Explorer等工具。还可以尝试使用动态分析工具来识别程序在何处打开和关闭文件。

如果您怀疑可执行文件存在问题,您需要在源代码中进行修复。如果您没有源代码,请将其退回给开发人员。 - user1864610
如果fopen是以只读模式完成的,那么尽管这是非常糟糕的编码质量,但至少不会对文件中的数据造成任何问题。但是,如果使用写入模式完成了该fopen,则现在很有可能会损坏该文件中的数据。 - jussij
3个回答

8
后果是文件描述符"泄漏"。操作系统使用某些描述符,并与打开的文件关联一些资源。如果你使用fopen没有关闭,那么该描述符将不会被清除,并将持续到程序关闭为止。
如果文件可能被多次打开,则这个问题会加剧。随着程序的运行,越来越多的描述符将被泄漏,直到最终操作系统拒绝或无法创建另一个描述符,在这种情况下,调用fopen失败。
如果您只提供可执行文件而不是源代码,则您的选择非常有限。在那时,您必须尝试反编译或手动重写汇编语言,这两种选项都不是很理想。
正确的做法是提交错误报告,然后获取更新/修复版本。

系统最终会因为内存限制而拒绝吗?还是有其他原因?例如,假设我们不断地使用fopen打开文件,并且我们有无限的内存,那么系统永远不会拒绝打开文件吗? - JoeVictor

2
如果有许多文件被打开但没有正确关闭,程序最终将耗尽文件句柄和/或内存空间并崩溃。
建议您联系开发人员更新他们的代码。

0

后果取决于 fclose / fopen 和相关函数的实现方式 - 它们是缓冲输入/输出函数。因此,写入的内容实际上首先被写入内部缓冲区 - 只有当代码“感觉到”时,缓冲区才会被刷新到输出 - 这可能是每行、每个完整块的每次写入,具体取决于实现的智能程度。

fopen 很可能使用 open 来获取操作系统的实际文件描述符 - 在大多数系统(Linux、Windows 等)中,当进程终止时,操作系统文件描述符将被关闭 - 但是如果程序没有终止,操作系统文件描述符将泄漏,最终会用尽文件描述符并死机。

一些标准可能规定程序在干净地终止或崩溃时采取特定的行为,但事实是,并非所有实现都遵循这种行为。

因此,您的风险是您的程序认为已经写入的某些数据将丢失 - 这将是坐落在内部缓冲区但从未刷新的数据 - 或者您可能会用尽文件描述符并死机。

所以,请修复代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接