fopen:保持开放或使用缓冲区是个好主意吗?

所以我有很多需要写的日志文件。 它们在程序开始时创建,并在程序关闭时保存到文件。

我想知道它是否更好:

fopen()在程序开始时,然后在程序结束时关闭文件 – 我只需要在需要时写入文件。 这些文件是否仍然“开放”会减慢任何事情(例如其他文件io)吗?

要么

我将需要写入的内容保存到缓冲区中,然后打开文件,从缓冲区写入,在程序结束时关闭文件。 我想这会更快?

好吧, fopen(3) + fwrite(3) + fclose(3) 一个缓冲的I / O包,所以在它上面的另一层缓冲可能只会减慢速度。

无论如何,请选择一个简单而正确的程序。 如果它似乎运行缓慢,对其进行分析,然后根据证据进行优化而不是猜测。

简短回答:

  1. 大量打开的文件不应该减慢任何速度
  2. 无论如何,写入文件将被缓冲

因此,您可以打开这些文件,但不要忘记检查操作系统中已打开文件的限制。

日志文件的一部分是能够弄清楚当程序遇到问题时发生了什么。 相当多的人也在(近)实时进行日志文件分析。 您的第二个场景不适用于其中任何一个。

我从第一种方法开始,但是如果你真的需要,可以使用足够高级别的接口切换到第二种方法。 我不认为该开关是高级接口的主要优点 – 真正的好处通常是保持其余代码更清洁。

没有充分的理由在程序中缓冲日志消息并在退出时将其写出来。 只需在使用fprintf生成它们时编写它们。 stdio系统将为您处理缓冲。 当然这意味着从头开始打开文件(使用fopen )并保持打开状态。

对于日志文件,您可能需要一个function接口,在每个完整消息之后将数据刷新到磁盘,这样,如果程序崩溃(已知会发生),则日志信息是安全的。 将内容留在标准I / O缓冲区中意味着从核心转储中挖掘数据 – 这比安全地获取磁盘上的信息要差。

其他I / O实际上不会受到打开一个 – 甚至几个 – 日志文件的影响。 你可能会丢失一些文件描述符,但这通常不是一个严重的问题。 当它出现问题时,您将一个文件描述符用于一个日志文件 – 并将其保持打开状态,以便您可以记录信息。 您可以选择将stderr映射到日志文件,将其保留为正在使用的文件描述符。

有人提到fopen返回的FILE *已经被缓冲了。 对于日志记录,您还应该考虑使用setbuf()或setvbuf()函数来更改FILE *的缓冲行为。

特别是,您可能希望将缓冲模式设置为一次一行,因此在写入每行后会自动刷新日志文件。 您还可以指定要使用的缓冲区的大小。