11

I have a good old C FILE file descriptor under Windows that is used by an output stream to write data to. My question is simple and yet I could not find the answer:

When is the content flushed to disc assuming I don't call fflush?

The stream constantly receives data and it seems that the content is flushed quite often, but what is the rule for flushing it?

anhoppe
  • 4,287
  • 3
  • 46
  • 58
  • 3
    Pretty sure it's up to the OS. – Phonon Apr 23 '13 at 07:08
  • BTW actually the code uses a wxTextOutputStream that uses a wxFFileOutoutStream that uses a wxFFile. But that only encapsulates a FILE structure so I guess the fflush mechanism is the interesting thing here... – anhoppe Apr 23 '13 at 07:09
  • 1
    If it's buffered,then it's flushed once the buffer is full.And I don't quite understand what you mean by FILE structure (fopen,fwrite,....) – Rüppell's Vulture Apr 23 '13 at 07:10
  • Yeah, think so, too. So maybe it is more a VS2010 C runtime question? – anhoppe Apr 23 '13 at 07:10
  • Sry, just wanted to hint. I mean the FILE file descriptor that is used by fopen, fwrite etc – anhoppe Apr 23 '13 at 07:12
  • So, buffer size depends on the os specific runtime then? – anhoppe Apr 23 '13 at 07:12
  • @anhoppe, Since you are using the CRT, you can define your own buffer size using [`setvbuf`](http://pubs.opengroup.org/onlinepubs/009695299/functions/setvbuf.html) though. Also, I think that the default buffer size is `BUFSIZ` defined in __stdio.h__. This value is compiler dependant. – Anish Ramaswamy Apr 23 '13 at 07:16
  • @anhoppe The other issue is that even if you control the FILE buffer with setvbuf, that gives no guarantee that the data will be written to the disc. There could be other layers of buffering that are outside your control. – john Apr 23 '13 at 07:17
  • @AnishRam: `BUFSIZ` depends on the library implementation, not the compiler. – DevSolar Apr 23 '13 at 07:19
  • @DevSolar, yeah. You're right. – Anish Ramaswamy Apr 23 '13 at 07:22
  • When you a) Close the file b) Unmount the device. On Linux there is a `sync` command. Otherwise you can't guarantee the data has landed on a physical device. – Valeri Atamaniouk Apr 23 '13 at 07:39

1 Answers1

15

If the library implementation can determine the output stream not to refer to an interactive device (and only then), the stream will be fully buffered, i.e. it will be flushed when the buffer (by default of BUFSIZ size) is full.

If not fully buffered, a stream can be line buffered, i.e. it will be flushed when an '\n' is written (or the buffer is full, if your line is really long), or unbuffered.

(ISO/IEC 9899:1999, chapter 7.19.5.3 "The fopen() function", paragraph 7. Don't have a newer version of the standard at hand, but AFAIK this didn't change.)

What constitutes an "interactive device" is implementation-defined. (Chapter 5.1.2.3 "Program execution", paragraph 6.)

The general idea is that file output should be fully buffered whereas terminal output be line buffered (or unbuffered, as Jesse Good correctly pointed out).

Both the buffering policy and the buffer size can be changed via setvbuf(). Note that any such change must happen before you start accessing the stream, which is somewhat obvious once you think about it.

DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • 1
    @anhoppe: I've actually *implemented* ``, and *boy* you better learn to read the fine print when you do that... :-D – DevSolar Apr 23 '13 at 07:18
  • +1 Additionally, the [C11 standard](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) specifies that `BUFSIZ` should be _at least_ 256. – Anish Ramaswamy Apr 23 '13 at 07:19
  • `In all other cases (interactive device or unable to determine), the stream will be line buffered` I don't think that is true, it can unbuffered also (which is how the terminal is on windows). – Jesse Good Apr 23 '13 at 07:25
  • @JesseGood What the standard literally says is that the stream is fully buffered if and only if it can be determined not to refer to an interactive device. Otherwise, it can be line buffered or unbuffered. – James Kanze Apr 23 '13 at 08:06
  • @JesseGood: Good catch. I've been in a bit too much of a hurry when I wrote that. The standard reference was wrong as well. – DevSolar Apr 23 '13 at 09:04