File Buffering
int fflush(FILE *stream);
void setbuf(FILE * restrict stream,char * restrict buf);
int setvbuf(FILE * restrict stream, char * restrict buf, int mode, size_t size);
Transferring data to or from a disk drive is a relatively
slow operation. As a result, it isn't feasible for a program to access a disk
file directly each time it wants to read or write a byte. The secret to
achieving acceptable performance is buffering: data written to a
stream is actually stored in a buffer area in memory; when it's full (or the
stream is closed), the buffer is "Hushed" (written to the actual
output device). Input streams can be buffered in a similar way: the buffer
contains data from the input device; input is read from this buffer instead of
the device itself. Buffering can result in enonnous gains in efficiency, since
reading a byte from a buffer or storing a byte in a buffer lakes hardly any
time at all. Of course, it takes time to transfer the buffer contents to or
from disk, but one large "block move" is much faster than many tiny
byte moves.
The functions in perform buffering
automatically when it seems advantageous. The buffering lakes place behind the
scenes, and we usually don't worry about it. On rare occasions, though, we may
need to lake a more active role. If so, we can use the functions f flush,
setbuf, and setvbuf.
When
a program writes output to a file, the data normally goes into a buffer first.
The buffer is flushed automatically when it's full or the file is closed. By
calling f flush, however, a program can flush a file's buffer as often as it
wishes. The call
fflush(fp); /*
flushes buffer for fp */
flushes the buffer for the file
associated with fp. The call fflush(NULL); /* flushes all buffers */
flushes all output streams, f flush returns
zero if it's successful and EOF if an error occurs.
setvbuf allows us to change the way a stream is
buffered and to control the size and location of the buffer. The function's
third argument, which specifies the kind of buffering desired, should be one of
the following macros:
IOFBF (full buffering). Data is read from the stream when the buffer is
empty or written to the stream when it's full.
IOLBF (line buffering). Data is read from the stream or written to the
stream one line at a lime.
IONBF (no buffering). Data is read from the stream or written to the
stream directly, without a buffer.
(All
three macros are defined in .) Full buffering is the default for
streams that aren't connected to interactive devices.
setvbuf's
second argument (if it's not a null pointer) is the address of the desired
buffer. The buffer might have static storage duration, automatic storage
duration, or even be allocated dynamically. Making the buffer automatic allows
its space to be reclaimed automatically at block exit: allocating it
dynamically enables us to free the buffer when it's no longer needed, setvbuf's
last argument is the number of bytes in the buffer. A larger buffer may give
better performance; a smaller buffer saves space.
setvbuf must be called after stream is opened but before any other operations
are performed on it.
When using setvbuf or setbuf, be sure to close
the stream before its buffer is deallocated. In particular, if the buffer is
local to a function and has automatic storage duration, be sure to close the
stream before the function returns.
No comments:
Post a Comment