Question

I understand that one of the advantages of using stdio.h FILE over direct read()/write() is the buffering, interrupt handling, etc. So, as I understand, all the fwrite()s get buffered up until I do an fclose(). So far, so good. Now, when I do an fclose(), will I block until the data is flushed to disk or will the fclose() return right away after handing the data over to the OS and letting it flush to disk at its leisure?

Was it helpful?

Solution

There are buffering at many levels, this depends on the OS and many other things.

Typically there's an internal buffer in the FILE* living in your application that is either flushed out to the file (or whichever device the FILE* is connected to)

  • when the internal FILE* buffer is full
  • when you've written a newline (in case of a line buffered FILE*)
  • when you close the FILE*
  • when you call fflush()
  • the FILE* could also be unbuffered

In the case of an ordinary disk file, most OS have buffering in the kernel, so flushing the FILE* buffer involves more or less just a copy of memory from the buffer of your application to the OS kernel, and the kernel will take care of writing it to the actual file at its leisure asynchronously, which will cause the fclose() to return "right away".

There could circumstances where the OS first have to do some housekeeping before the data is copied into the OS/kernel buffers, e.g. it might have to flush out data to the physical file to make room for more data, allocate space in the file to ensure there is room and so on, making it not return instantly.

In short, it depends, and you cannot control it. Usually the "best" you can do is use platform dependent APIs that at least allow you to flush the OS buffers to the physical file, such as the posix fsync()/fdatasync() APIs.

OTHER TIPS

Your understanding is (at least partially) wrong.

The I/O is buffered, but there are limits to the buffer sizes. When the buffers overflow, they will be flushed. Also, many streams are line-buffered; when you write a line feed, the buffer is flushed. If this were not the case, outputting to a terminal would be pretty impractical with all output appearing when the program terminates.

I don't think the calls are necessarily blocking otherwise, there are functions that try to make sure the underlying media is synced with the writes for instance. This commonly creates issues where you get "too low-level" and need to deal with the complexities of caches and buffers both the software but also in the hardware for e.g. hard drives.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top