views:

441

answers:

1

I thought fsync() does fflush() internally so using fsync() on a stream is OK. But i am getting unexpected result when executed under network I/O.

My code snippet:

  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);   

But it seems _commit() is not flushing the data (i tried on Windows and the data was written on Linux exported filesystem).

When i changed the code as:

 FILE* fp = fopen(file,"wb");   
   /* multiple fputs() call like: */   
   fputs(buf, fp);   
   ...   
   ...   
   fputs(buf.c_str(), fp);   
   /* fflush the data */   
   fflush(fp);   
   fclose(fp);    

This time it flushes the data.

I am wondering if _commit() does the same thing as fflush(). Any inputs?

+3  A: 

fflush() works on FILE* , it just flushes the internal buffers in the FILE* of your application out to the OS.

fsync works on a lower level, it tells the OS to flush its buffers to the physical media.

OSs heavily caches 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 lives in the OS kernel, typically.

nos
Thanks i was thinking on the same line. So if we are using FILE* then the same can be achieved by fflush() followed by fsync().
Adil