fflush 和 fsync 之间的区别
题
我想 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);
但似乎 _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);
它刷新数据。
我想知道是否 _commit()
做同样的事情 fflush()
. 。有任何输入吗?
解决方案
fflush()
工作在FILE*
,它只是刷新内部缓冲区中应用程序的FILE*
出到操作系统。
在一个较低的水平fsync
作品,它告诉OS刷新其缓冲区的物理介质。
操作系统很大程度上缓存你写一个文件的数据。如果操作系统执行每个写打的驱动器,事情会的非常的慢。 fsync
(除其他外),可以控制当数据应该打的驱动器。
此外,FSYNC /提交上的文件描述符作品。它没有一个FILE*
的知识,不能刷新其缓冲区。 FILE*
生活在你的应用程序,文件描述符住在操作系统内核,一般。
其他提示
在标准C函数fflush()
和POSIX系统调用fsync()
在概念上有些类似。 fflush()
上C文件流(FILE
对象)进行操作,因此是便携的。
fsync()
对POSIX文件描述符操作。
两个原因缓冲的数据被发送到的目的地。
在一个POSIX系统中,每个C文件流具有关联的文件描述符一>,并且所有在C文件流的操作将被通过委派,在必要时,就在文件描述符操作POSIX系统调用来实现。
有人可能认为到fflush
呼叫的POSIX系统上会导致在文件流的缓冲器的任何数据,然后write
的该文件流的文件描述符的呼叫的fsync()
。因此,一个POSIX系统上就没有必要遵循fflush
调用一起fsync(fileno(fp))
通话。但是,这是的情况下:是有从fsync
到fflush
呼叫
没有,调用POSIX系统上fflush
并不意味着fsync
将被调用。
有fflush
C标准说(强调)它
使得用于[该]流的任何未写入的数据被传递到主机环境的要被写入到文件
说该数据是是写的,而不是为就是写入意味着由主机环境,进一步缓冲是允许的。由“主机环境”缓冲可能包括一个POSIX环境,内部缓冲使fsync
刷新。所以,C标准的细读表明,标准不要求POSIX实施呼叫fsync
。
我可以说,为简单起见:
使用与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
fflush()
和 fsync()
可用于尝试确保数据写入存储介质(但并不总是可行):
- 第一次使用
fflush(fp)
在输出流上(fp
成为一个FILE *
从...获取fopen
或标准流之一stdout
或者stderr
) 将与流关联的缓冲区的内容写入操作系统。 - 然后使用
fsync(fileno(fp))
告诉操作系统将自己的缓冲区写入存储介质。
但请注意 fileno()
和 fsync()
POSIX 函数可能并非在所有系统上都可用,尤其是 Microsoft 旧系统,其中可能会命名替代函数 _fileno()
, _fsync()
或者 _commit()
...
要强制的最近的变化到磁盘的承诺,使用同步()或FSYNC()函数。
<强> FSYNC() 强>将同步所有给定的文件的数据和元数据的与永久存储设备。它应该被称为相应的文件已被关闭之前发生。
<强> 同步() 强>将所有修改过的文件提交至磁盘。
我认为从下面蟒文件( https://docs.python.org/ 2 /库/ os.html )澄清很好。
os.fsync(FD)与文件描述符文件的力的fd写入到磁盘。上 Unix中,调用本地的fsync()函数;在Windows上,MS _commit()函数。
如果你已经从一个Python文件对象f,首先做f.flush() 然后做os.fsync(f.fileno()),以确保所有的内部缓冲区 使用f相关联的写入磁盘。
状况:。Unix和Windows开始在2.2.3