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()将所有修改的文件提交到磁盘。