Library I/O Functions in Unix/Linux: File Stream Buffering

Every file stream has a FILE structure, which contains an internal buffer. Read from or write to a file stream goes through the internal buffer of the FILE structure. A file stream may employ one of three kinds of buffering schemes.

. unbuffered: characters written to or read from an unbuffered stream are transmitted individually to or from the file as soon as possible. For example, the file stream stderr is usually unbuffered. Any outputs to stderr will appear immediately.

. line buffered: characters written to a line buffered stream are transmitted in blocks when a newline char is encountered. For example, the file stream stdout is usually line buffered. It outputs data line by line.

. fully buffered: characters written to or read from a fully buffered stream are transmitted to or from the file in block size. This is the normal buffering scheme of file streams.

After creating a file stream by fopen() and before any operation has been performed on it, the user may issue a

setvbuf(FILE *stream, char *buf, int node, int size)

call to set the buffer area (buf), buffer size (size) and buffering scheme (mode), which must be one of the macros

_IONBUF: unbuffered

_IOLBUF: line buffered

_IOFBUF: fully buffered

In addition, there are other setbuf() functions, which are variants of setvbuf(). The reader may consult the man pages of setvbuf for more details.

For line or fully buffered streams, fflush(stream) can be used to flush out the stream’s buffer immediately. We illustrate the different buffering schemes by an example.

Example 9.6. FILE stream buffering: Consider the following C program

#include <stdio.h>
int main()
{

(1). // setvbuf(stdout, NULL, _IONBF, 0);

      while(1){

(2).        printf(“hi “); // not a line yet

(3).        // fflush(stdout);

           sleep(1); // sleep for 1 second

      }

}

When running the above program, no outputs will appear immediately despite the printf() statement at line (2) on each second. This is because stdout is line buffered. Outputs will appear only when the printed chars fill the internal buffer of stdout, at which time, all the previously printed chars will appear at once. So, if we do not write lines to stdout, it behaves as a fully buffered stream. If we uncomment line (3), which flushes out stdout, each print will appear immediately despite it is not a line yet. If we uncomment line (1), which sets stdout to unbuffered, then the printing will appear on each second.

Source: Wang K.C. (2018), Systems Programming in Unix/Linux, Springer; 1st ed. 2018 edition.

Leave a Reply

Your email address will not be published. Required fields are marked *