Adi*_*dil 50 c windows fsync fflush
我认为fsync()在内部执行fflush(),因此在流上使用fsync()是可以的.但是我在网络I/O下执行时会得到意想不到的结果.
我的代码片段:
FILE* fp = fopen(file, "wb");
/* multiple fputs() calls 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);
Run Code Online (Sandbox Code Playgroud)
但似乎_commit()并没有刷新数据(我在Windows上试过并且数据是在Linux导出的文件系统上编写的).
当我将代码更改为:
FILE* fp = fopen(file, "wb");
/* multiple fputs() calls like: */
fputs(buf, fp);
...
...
fputs(buf.c_str(), fp);
/* fflush the data */
fflush(fp);
fclose(fp);
Run Code Online (Sandbox Code Playgroud)
这次它会刷新数据.
我想知道_commit()是否与fflush()做同样的事情.有什么投入?
nos*_*nos 79
fflush()继续工作FILE*,它只是将FILE*应用程序中的内部缓冲区刷新到操作系统.
fsync 它工作在较低级别,它告诉操作系统将其缓冲区刷新到物理介质.
操作系统会大量缓存您写入文件的数据.如果操作系统强制每次写入命中驱动器,事情就会非常缓慢.fsync(除此之外)允许您控制数据何时应该到达驱动器.
此外,fsync/commit适用于文件描述符.它不知道a FILE*并且不能刷新缓冲区.FILE*通常存在于您的应用程序中,文件描述符存在于操作系统内核中.
标准C函数fflush()和POSIX系统调用fsync() 在概念上有些相似.fflush()在C文件流(FILE对象)上运行,因此是可移植的.
fsync()对POSIX文件描述符进行操作.两者都会导致缓冲数据被发送到目的地.
在POSIX系统上,每个C文件流都有一个关联的文件描述符,并且必要时,通过委托对文件描述符进行操作的POSIX系统调用来实现C文件流上的所有操作.
有人可能会认为fflush对POSIX系统的调用会导致write文件流缓冲区中的任何数据,然后调用fsync()该文件流的文件描述符.因此,在POSIX系统上,无需通过呼叫来跟随fflush呼叫fsync(fileno(fp)).但情况是这样的:是否有fsync来自的电话fflush?
不,调用fflushPOSIX系统并不意味着fsync会调用它.
C标准fflush说(重点补充)它
导致[流]的任何未写入数据被传递到主机环境以写入文件
说的数据是要被写入,而不是是被写入意味着由主机环境进一步缓冲是允许的.对于POSIX环境,"主机环境"的缓冲可以包括fsync刷新的内部缓冲.因此仔细阅读C标准表明该标准不需要POSIX实现来调用fsync.
所述的POSIX标准描述fflush不声明,作为与c语义的扩展,即fsync被调用.