【问题标题】:fopen: is it good idea to leave open, or use buffer?fopen:保持打开状态或使用缓冲区是个好主意吗?
【发布时间】:2011-01-29 05:35:58
【问题描述】:

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

我想知道这样做是否更好:

fopen() 在程序开始时,然后在程序结束时关闭文件 - 我会在需要时写入文件。如果这些文件仍然“打开”,是否会减慢任何内容(例如其他文件 io)?

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

【问题讨论】:

    标签: c++ c file io


    【解决方案1】:

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

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

    【讨论】:

    • +1,在程序运行时也写入一些缓冲区并不一定意味着它会在发生崩溃时被写入。最好在磁盘上尽可能多地保存。
    【解决方案2】:

    简答:

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

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

    【讨论】:

    • 在讨论缓冲和非缓冲 I/O 时,这些术语几乎总是指用户程序将什么交给内核,而不是内核做或不做的事情。在大多数情况下,说 “将由内核缓冲”是不正确的。 如果您的意思是 “由 C 运行时库”, 那么是的,我同意.
    • 我想它也可能取决于操作系统
    • 啊,谢谢。我知道 C++ 的 io 被缓冲了——不确定 C 的。我可以在任何地方阅读基本 IO 和良好实践(以及最快的做事方式)?
    【解决方案3】:

    日志文件的部分意义在于能够弄清楚当/如果您的程序遇到问题时发生了什么。相当多的人还(近乎)实时地进行日志文件分析。您的第二种情况不适用于其中任何一种。

    我会从第一种方法开始,但如果你真的需要,你可以切换到第二种方法。不过,我不认为这种切换是高级接口的主要好处——真正的好处通常是使其余代码更简洁。

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        对于日志文件,您可能需要一个在每条完整消息后将数据刷新到磁盘的功能接口,以便如果程序崩溃(它已经已知发生),日志信息是安全的。将内容留在标准 I/O 缓冲区中意味着从核心转储中挖掘数据 - 这不如将信息安全地保存在磁盘上。

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

        【讨论】:

        • 你有没有好的日志系统的例子?最好是准系统?
        • @Pepe:一个选项——不一定是最小的——是log4c。我没用过。我通常使用我自己的 stderr 包 - 作为 SQLCMD 程序的一部分,可以从 IIUG Software Archive 轻松获得 - 或者您可以直接与我联系(请参阅我的个人资料)。
        【解决方案6】:

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

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

        【讨论】:

        • 好点,但默认情况下 fopen 在大多数 Unix 上以行模式打开文件。在 Windows/DOS 世界中,您必须以文本模式打开文件(fopen("file.txt", "wt") 以在没有 setbuv 的情况下启用该行为。
        猜你喜欢
        • 2021-02-06
        • 1970-01-01
        • 2018-06-13
        • 2017-01-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多