fflush和fsync之间的区别

时间:2010-02-26 09:36:11

标签: fflush fsync c windows

我认为fsync()在内部执行fflush(),因此在流上使用fsync()是可以的。但是我在网络I / O下执行时会得到意想不到的结果。

我的代码段:

FILE* fp = fopen(file,"wb");
/* multiple fputs() call like: */
fputs(buf, fp);
...
...
fputs(buf.c_str(), fp);
/* get fd of the FILE pointer */
fd = fileno(fp);
#ifndef WIN32
ret = fsync(fd);
#else
ret = _commit(fd);
fclose(fp);

但似乎_commit()没有刷新数据(我在Windows上试过并且数据是在Linux导出的文件系统上编写的)。

当我将代码更改为:

FILE* fp = fopen(file,"wb");
/* multiple fputs() call like: */
fputs(buf, fp);   
...   
...
fputs(buf.c_str(), fp);
/* fflush the data */
fflush(fp);
fclose(fp);

这次刷新数据。

我想知道_commit()是否与fflush()做同样的事情。有什么输入吗?

6 个答案:

答案 0 :(得分:73)

fflush()适用于FILE*,它只是将应用程序FILE*中的内部缓冲区刷新到操作系统。

fsync在较低级别工作,它告诉操作系统将其缓冲区刷新到物理介质。

操作系统会大量缓存您写入文件的数据。如果操作系统强制每次写入命中驱动器,那么事情就会非常慢。 fsync(除其他外)允许您控制数据何时应该到达驱动器。

此外,fsync / commit适用于文件描述符。它不知道FILE*并且无法刷新其缓冲区。 FILE*存在于您的应用程序中,文件描述符通常存在于操作系统内核中。

答案 1 :(得分:5)

标准C函数fflush()和POSIX系统调用fsync()在概念上有些相似。 fflush()对C文件流(FILE对象)进行操作,因此是可移植的。 fsync()对POSIX文件描述符进行操作。 两者都会导致缓冲数据被发送到目的地。

在POSIX系统上,每个C文件流has an associated file descriptor以及C文件流上的所有操作都将通过在必要时委托对文件描述符进行操作的POSIX系统调用来实现。

有人可能会认为在POSIX系统上调用fflush会导致文件流缓冲区中的write个数据,然后调用fsync()该文件流的文件描述符。因此,在POSIX系统上,无需通过调用fflush来跟随fsync(fileno(fp))的来电。但情况是这样的:是否有来自fsync的{​​{1}}来电?

不,在POSIX系统上调用fflush并不意味着将调用fflush

fsync的C标准说(强调添加)

  

导致[流]的任何未写入数据被传递到主机环境以写入到文件

假设数据写入,而不是 写入,这意味着允许主机环境进一步缓冲。对于POSIX环境,“主机环境”的缓冲可以包括fflush刷新的内部缓冲。因此仔细阅读C标准表明该标准不要求POSIX实现调用fsync

POSIX standard description of fflush并未声明fsyncfsync,而是print( df.groupby('clienthostid') .LoginDaysSum.nlargest(2) .sort_values() .groupby(level=0) .pct_change().dropna().add(1) .reset_index(1, drop=True) ) clienthostid 1 4.000000 3 6.387707 Name: LoginDaysSum, dtype: float64

答案 2 :(得分:2)

为简单起见,我可以说:

使用fsync()而非流文件(整数文件描述符)

fflush()与文件流一起使用。

这也是男人的帮助:

int fflush(FILE *stream); // flush a stream, FILE* type

int fsync(int fd); // synchronize a file's in-core state with storage device
                    // int type

答案 3 :(得分:0)

要强制最近更改磁盘的承诺,请使用sync()或fsync()函数。

fsync() 会将所有给定文件的数据和元数据与永久存储设备同步。它应该在相应文件关闭之前调用。

sync() 会将所有已修改的文件提交到磁盘。

答案 4 :(得分:0)

我认为python(https://docs.python.org/2/library/os.html)下面的文档很清楚地说明了这一点。

  

os.fsync(fd)强制将filedescriptor fd文件写入磁盘。上   Unix,这称为本机fsync()函数;在Windows上,MS   _commit()函数。

     

如果您从Python文件对象f开始,首先执行f.flush(),   然后执行os.fsync(f.fileno()),以确保所有内部缓冲区   与f关联的内容写入磁盘。

     

可用性:Unix和Windows从2.2.3开始。

答案 5 :(得分:0)

fflush()fsync()可用于尝试确保将数据写入存储介质(但这并不总是可能的):

  1. 首先在输出流上使用fflush(fp)fp是从FILE *或标准流fopen或{{1}中获得的stdout })将与流相关联的缓冲区的内容写入操作系统。
  2. 然后使用stderr告诉操作系统将其自己的缓冲区写入存储介质。

但是请注意,fsync(fileno(fp))fileno()是POSIX函数,可能并非在所有系统上都可用,特别是Microsoft旧版系统,在这些旧版系统中,替代项可能命名为fsync()_fileno()_fsync() ...