【问题标题】:Will fseek function flush data in the buffer in C++?fseek 函数会在 C++ 中刷新缓冲区中的数据吗?
【发布时间】:2011-11-21 16:37:32
【问题描述】:

我们知道调用 fprintf 或 fwrite 等函数不会立即将数据写入磁盘,而是会缓冲数据直到达到阈值。我的问题是,如果我调用 fseek 函数,这些缓冲数据会在寻找新位置之前写入磁盘吗?还是数据还在缓冲区中,正在写入新位置?

【问题讨论】:

    标签: c++ file fseek


    【解决方案1】:

    我不知道缓冲区是否保证被刷新,如果你寻求一个足够接近的位置,它可能不会。但是,缓冲的数据无法写入新位置。缓冲只是一种优化,因此它必须是透明的。

    【讨论】:

    • 所以你的意思是这种调用没问题:(1)fwrite...(2)fseek...(3)fwrite... 所有数据都会在正确的位置?
    • 是的,您可以确定fseek 会像根本没有缓冲一样工作。
    • 你能引用 C 标准中的文本来支持这个观点吗? (我认为这是不正确的,但我这里没有 C 标准的副本来验证。)而且缓冲当然不是“只是一种优化”;该标准涵盖了缓冲的许多方面(例如fflushsetbuf 等)
    【解决方案2】:

    是的; fseek() 确保根据您执行的fwrite() 操作,文件看起来应该是它应该的样子。

    C 标准 ISO/IEC 9899:1999 §7.19.9.2 fseek() 说:

    fseek 函数为 stream 指向的流设置文件位置指示符。 如果发生读取或写入错误,则会设置流的错误指示器并且 fseek 失败。

    【讨论】:

    • 他实际上是在询问fseek()
    • 鉴于您的答案文本和您引用的部分,您是说fseek 必须等同于fflush?我不太清楚。
    【解决方案3】:

    我不认为它指定必须在 fseek 上刷新数据,但是当数据实际写入磁盘时,它必须写入到调用 write 函数时流所在的位置。即使数据仍在缓冲中,该缓冲区在刷新时也无法写入文件的其他部分,即使有后续查找。

    【讨论】:

      【解决方案4】:

      看来您真正关心的是,如果您执行fseek,之前写入(但尚未刷新)的数据是否会最终出现在文件中的错误位置。

      不,这不会发生。它会按照您的预期运行。

      【讨论】:

        【解决方案5】:

        我对您之前致电fflush 的要求有模糊记忆 fseek,但我没有可用于验证的 C 标准副本。 (如果你不这样做,那将是未定义的行为或定义的实现, 或类似的东西。)通用 Unix 标准规定:

        如果给定流上的最新操作(除 ftell() 之外)是 fflush(),底层打开文件描述中的文件偏移量 应调整以反映 fseek() 指定的位置。

        [...]

        如果流是可写的并且缓冲的数据没有被写入 底层文件 fseek() 将导致未写入的数据 写入文件并标记 st_ctime 和 st_mtime 字段 要更新的文件。

        然而,这被标记为对 ISO C 标准的扩展,因此除了 Unix 平台(或做出类似保证的其他平台)之外,您不能指望它。

        【讨论】:

        • 考虑例如 7.19.5.3/6:“在没有对 fflush 函数或文件定位函数(fseek、fsetpos 或 rewind)的干预调用的情况下,输出不应直接跟随输入”。这不是确定的,但如果需要在输出之后和fseek 之前调用fflush,那么提到fseek 将是多余的,因为无论如何都会有刷新。
        • @Steve 这可能是我在考虑的限制 --- 正如我所说,我模糊地记得要求致电fflush,但我没有我的标准副本可以方便地验证它的位置(而且由于我通常只使用 C++ I/O,因此我不记得 C 风格的 IO)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-23
        • 1970-01-01
        相关资源
        最近更新 更多