fflush和fsync之间的区别

我认为fsync()在内部执行fflush(),因此在stream上使用fsync()是可以的。 但是当我在networkingI / 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()做同样的事情。 任何投入?

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

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

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

而且,fsync / commit在文件描述符上工作。 它不知道FILE* ,不能刷新缓冲区。 FILE*存在于您的应用程序中,文件描述符通常位于OS内核中。

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

在POSIX系统上,每个C文件stream都有一个关联的文件描述符 ,并且在C文件stream上的所有操作都将通过在必要时将其委托给在文件描述符上操作的POSIX系统调用来实现。

有人可能会认为,调用POSIX系统上的fflush会导致write文件stream的缓冲区中的任何数据,然后调用fsync()作为该文件stream的文件描述符。 所以在一个POSIX系统上,不需要通过调用fsync(fileno(fp))fsync(fileno(fp)) fflush 。 但是是这样的情况:是否有从fflush调用fsync

不,在一个POSIX系统上调用fflush并不意味着会fsync

fflush的C标准说(强调加了)它

导致将任何未写入的数据stream传送到主机环境以写入文件

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

fflush的POSIX标准描述没有声明,作为C语义的扩展 , fsync被调用。

我可以说,为了简单:

使用fsync()而不是stream文件(整数文件描述符)

使用fflush()和文件stream。

这里还有人的帮助:

 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 

要强制最近对磁盘进行更改,请使用sync()或fsync()函数。

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

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