I thought fsync() does fflush() internally, so using fsync() on a stream is OK. But I am getting an unexpected result when executed under network I/O.
My code snippet:
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);
But it seems _commit() is not flushing the data (I tried on Windows and the data was written on a Linux exported filesystem).
When I changed the code to be:
FILE* fp = fopen(file, "wb");
/* multiple fputs() calls like: */
fputs(buf, fp);
...
...
fputs(buf.c_str(), fp);
/* fflush the data */
fflush(fp);
fclose(fp);
it flushes the data.
I am wondering if _commit() does the same thing as fflush(). Any inputs?
fflush()works onFILE*, it just flushes the internal buffers in theFILE*of your application out to the OS.fsyncworks on a lower level, it tells the OS to flush its buffers to the physical media.OSs heavily cache data you write to a file. If the OS enforced every write to hit the drive, things would be very slow.
fsync(among other things) allows you to control when the data should hit the drive.Furthermore, fsync/commit works on a file descriptor. It has no knowledge of a
FILE*and can’t flush its buffers.FILE*lives in your application, file descriptors live in the OS kernel, typically.