我们知道调用 fprintf 或 fwrite 等函数不会立即将数据写入磁盘;相反,数据将被缓冲,直到达到阈值。我的问题是: 如果我调用 fseek 函数,这些缓冲数据会在查找新位置之前写入磁盘吗?或者数据还在缓冲区中,并被写入到新的位置?
是的;
fseek()
确保文件看起来与您执行的 fwrite()
操作一致。
C 标准 ISO/IEC 9899:1999 §7.19.9.2
fseek()
表示:
fseek函数为stream所指向的流设置文件位置指示符。 如果发生读取或写入错误,则会设置流的错误指示符并且 fseek 失败。
我不知道缓冲区是否保证被刷新,如果您寻求足够接近的位置,则可能不会。但是,缓冲数据无法写入新位置。缓冲只是一种优化,因此它必须是透明的。
我不认为指定数据必须刷新在
fseek
上,但是当数据实际写入磁盘时,必须将其写入调用写入函数时流所在的位置。即使数据仍在缓冲中,该缓冲区在刷新时也无法写入文件的其他部分,即使已经进行了后续查找。
看来您真正关心的是,如果您执行
fseek
,先前写入(但尚未刷新)的数据是否会最终出现在文件中的错误位置。
不,那不会发生。它会按照您的预期运行。
我依稀记得你之前打电话给
fflush
的一个要求
fseek
,但我没有可供验证的 C 标准副本。
(如果不这样做,这将是未定义的行为或定义的实现,
或类似的东西。)通用 Unix 标准指定:
如果给定流上除 ftell() 之外的最近操作是 fflush(),底层打开文件描述中的文件偏移量 应调整以反映 fseek() 指定的位置。
[...]
如果流可写并且缓冲数据尚未写入 底层文件,fseek() 将导致未写入的数据 写入文件并应标记 st_ctime 和 st_mtime 字段 用于更新的文件。
然而,这被标记为 ISO C 标准的扩展,因此除了 Unix 平台(或做出类似保证的其他平台)之外,您不能指望它。