【发布时间】:2011-01-29 05:35:58
【问题描述】:
所以我有很多需要写入的日志文件。它们在程序开始时创建,并在程序关闭时保存到文件中。
我想知道这样做是否更好:
fopen() 在程序开始时,然后在程序结束时关闭文件 - 我会在需要时写入文件。如果这些文件仍然“打开”,是否会减慢任何内容(例如其他文件 io)?
或
我将需要写入的内容保存到缓冲区中,然后在程序结束时打开文件,从缓冲区写入,关闭文件。我想这会更快吗?
【问题讨论】:
所以我有很多需要写入的日志文件。它们在程序开始时创建,并在程序关闭时保存到文件中。
我想知道这样做是否更好:
fopen() 在程序开始时,然后在程序结束时关闭文件 - 我会在需要时写入文件。如果这些文件仍然“打开”,是否会减慢任何内容(例如其他文件 io)?
或
我将需要写入的内容保存到缓冲区中,然后在程序结束时打开文件,从缓冲区写入,关闭文件。我想这会更快吗?
【问题讨论】:
嗯,fopen(3) + fwrite(3) + fclose(3) 是一个缓冲的 I/O 包,所以在它上面的另一层缓冲可能只会减慢速度。
无论如何,选择一个简单而正确的程序。如果它看起来运行缓慢,请对其进行分析,然后根据证据而不是猜测进行优化。
【讨论】:
简答:
因此您可以让这些文件保持打开状态,但不要忘记检查您的操作系统中打开文件的限制。
【讨论】:
日志文件的部分意义在于能够弄清楚当/如果您的程序遇到问题时发生了什么。相当多的人还(近乎)实时地进行日志文件分析。您的第二种情况不适用于其中任何一种。
我会从第一种方法开始,但如果你真的需要,你可以切换到第二种方法。不过,我不认为这种切换是高级接口的主要好处——真正的好处通常是使其余代码更简洁。
【讨论】:
没有充分的理由在程序中缓冲日志消息并在退出时将它们写出。只需在使用fprintf 生成它们时编写它们。 stdio 系统将为您处理缓冲。当然,这意味着从头开始打开文件(使用fopen)并保持打开状态。
【讨论】:
对于日志文件,您可能需要一个在每条完整消息后将数据刷新到磁盘的功能接口,以便如果程序崩溃(它已经已知发生),日志信息是安全的。将内容留在标准 I/O 缓冲区中意味着从核心转储中挖掘数据 - 这不如将信息安全地保存在磁盘上。
打开一个或什至几个日志文件并不会影响其他 I/O。您可能会丢失一些文件描述符,但这通常不是一个严重的问题。当出现问题时,您对一个日志文件使用一个文件描述符 - 并保持打开状态以便记录信息。您可以选择将stderr 映射到日志文件,将其作为正在使用的文件描述符。
【讨论】:
stderr 包 - 作为 SQLCMD 程序的一部分,可以从 IIUG Software Archive 轻松获得 - 或者您可以直接与我联系(请参阅我的个人资料)。
已经提到 fopen 返回的 FILE* 已经被缓冲了。对于日志记录,您可能还应该考虑使用 setbuf() 或 setvbuf() 函数来更改 FILE* 的缓冲行为。
特别是,您可能希望将缓冲模式设置为一次一行,以便在写入每一行后自动刷新日志文件。您还可以指定要使用的缓冲区大小。
【讨论】:
fopen("file.txt", "wt") 以在没有 setbuv 的情况下启用该行为。