UNIX full-buffered, row-buffered, unbuffered

Source: Internet
Author: User

the stream-based operation will eventually call the read or write function for I/O operations. To make the program run most efficiently, the stream object typically provides buffers to reduce the number of times the system I/O library functions are called.

Stream-based I/O provides the following 3 types of buffering:

Full buffering: The system I/O function is not called until the buffer is filled. For a read operation, the actual I/O operation is not performed until the bytes of the read-in content are equal to the buffer size or the file has reached the end, the contents of the external memory file are read into the buffer, and for the write operation until the buffer is filled, the buffer contents are written to the external memory file. disk files are usually fully buffered.

Row buffering: The system I/O library function is not called until a newline character ' \ n ' is encountered. For the read operation, I/O is encountered by the newline character ' \ n ', the read content is read into the buffer, and the newline character ' \ n ' is encountered for the write operation, and the buffer contents are written to external memory. Because the size of the buffer is limited, the actual I/O operation is also performed when the buffer is filled, even if no newline character ' \ n ' is encountered. the standard input stdin and standard output stdout are row buffered by default .

Unbuffered: Without buffers, data is immediately read into or output to external memory files and devices . Standard error stderr is unbuffered, so that the error prompt and output can be timely feedback to the user, for the user to troubleshoot errors.

The above 3 buffers are defined as 3 macros, which are defined as shown in table 21-1.

Table 21-1 macro definitions for buffer types

Buffer type

Defined macros

Full buffer

_io_full_buf

Row buffers

_io_line_buf

No buffering

_io_unbuffered

When you use the buffer type macro described in the previous table, you should make the "and" action of the buffer flag in the file stream object with the macro and determine if the result is 0 to know whether the buffer of the buffered file stream belongs to that type. The following example shows the type of buffer that gets the file stream. The program output standard output, standard input, and standard error 3 file descriptor buffer type, buffer size and other information.

BUF.C type and buffer size of output buffers

#include <stdio.h>intMainvoid) {printf ("stdin is");if(Stdin->_flags &_io_unbuffered) printf ("unbuffered\n");Else if(Stdin->_flags &_io_line_buf) printf ("line-buffered\n");Elseprintf ("fully-buffered\n");p rintf ("buffer size is%d\n", Stdin->_io_buf_end-stdin-_io_buf_base); printf ("Discriptor is%d\n\n", Fileno (stdin)); printf ("stdout is");if(Stdout->_flags &_io_unbuffered) printf ("unbuffered\n");Else if(Stdout->_flags &_io_line_buf) printf ("line-buffered\n");Elseprintf ("fully-buffered\n");p rintf ("buffer size is%d\n", Stdout->_io_buf_end-stdout-_io_buf_base); printf ("Discriptor is%d\n\n", Fileno (stdout)); printf ("stderr is");if(Stderr->_flags &_io_unbuffered) printf ("unbuffered\n");Else if(Stderr->_flags &_io_line_buf) printf ("line-buffered\n");Elseprintf ("fully-buffered\n");p rintf ("buffer size is%d\n", Stderr->_io_buf_end-stderr-_io_buf_base); printf ("Discriptor is%d\n\n", Fileno (stderr)); return 0;}

Output:

StdIn is fully-buffered
Buffer size is 0
Discriptor is 0

STDOUT is line-buffered
Buffer size is 1024
Discriptor is 1

STDERR is unbuffered
Buffer size is 0
Discriptor is 2

Strange, we do not say stdin is line buffer, why above output of Fully-buffer???

See the APUE--UNIX Environment Advanced Programming has the following content:

1. Buffer type.

The standard library provides buffering to reduce calls to read and write. There are three types of buffers available (organized from APUE):

    • Fully buffered.

In this case, the actual I/O operation occurs only after the buffer is filled. The operation of a file residing on disk is generally a standard I/O library that provides full buffering. Buffers are typically assigned by the malloc function called by standard I/O functions when I/O operations are performed on the first stream.

The term flush describes the write operation for standard I/O buffers. Buffers can be automatically flushed by standard I/O functions (for example, when the buffer is full), or we call the Fflush function for convection.

    • Row buffers

In this case, the actual I/O operation is performed only when a line break is encountered in the input/output. This allows us to write one character at a time, but I/O is only done after a line has been written. In general, flows that involve the terminal-such as callout input (stdin) and standard output (STDOUT)-are line buffered.

    • No buffering

The standard I/O library does not cache characters. It is important to note that the standard library does not cache and does not imply that the operating system or device drivers do not cache.

ISO C Requirements:

    • Standard input and standard output are fully cached when and only if no interaction devices are involved.
    • Standard errors are definitely not fully cached.

However, this does not tell us whether the standard input/output is cache-free or row-cached when it comes to interacting devices, nor does it tell us whether the standard error should be row-cached or non-cached. However, most implementations of the default cache type are:

    • Standard errors are always non-cached.
    • for all other streams, if they involve an interactive device, it is the row cache; otherwise it is fully cached .

The above program stdin does not involve input, so it is fully cached if we add one before the int main function:

int A;
scanf ("%d", &a);

Then the output becomes:

StdIn is line-buffered
Buffer size is 1024
Discriptor is 0

After using redirection, execute the program as follows:

$./buf < in.txt 1> OUT.txt 2> err.txt
StdIn is full-buffered
Buffer size is 4096
Discriptor is
STDOUT is full-buffered
Buffer size is 4096
Discriptor is 1
STDERR is unbuffered
"Buffer size is 0
Discriptor is 2

2. Change the default cache type

You can change the cache type by using the following function (excerpt from APUE):

void Setbuf (FILE *restrict fp, char *restrict buf);
int setvbuf (FILE *restrict fp, Char *restrict buf, int mode, size_t size);

These functions must be called after the stream has been opened, but not before the convection does anything (because each function requires a valid file pointer as the first parameter).

With Setbuf, you can turn caching on or off. In order to open the cache, the BUF parameter must be a cache of size bufsiz, Bufsiz is defined in stdio. The constants in H. &amp;lt;&amp;lt;iso/iec 9899&amp;gt;&amp;gt; Requirements: Bufsiz is at least 256. If you want to turn off caching, you can set BUF to null.

With Setvbuf, we can set the cache type. This is specified by the mode parameter.

For these two functions, you can look at the following table (excerpt from Apue):

f Unction

mode

buf

buffer and length

type of buffering

Setbuf

Non-null

User buf of length bufsiz

Fully buffered or line buffered

Null

(No buffer)

unbuffered

Setvbuf

_iolbf

Non-null

User buf of length size

Fully buffered

Null

System buffer of appropriate length

_iofbf

Non-null

User buf of length size

Line buffered

Null

System buffer of appropriate length

_ionbf

(ignored)

(No buffer)

unbuffered

It is important to note that if the flow is assigned an automatic variable within the function as the cache, the stream needs to be closed before exiting. It is therefore better to have the system allocate its own cache, which is automatically freed when the stream is closed.

3. If you clean the input cache

Refer to the COMP.LANG.C FAQ's question12.26b for this point:

Q:if Fflush won ' t work, what can I use to flush input?

A:It depends on "What are You" re trying to do. If you ' re trying to get rid of a unread newline or other unexpected input after calling scanf (see questions 12.18a-12.19 ), you really need to rewrite or replace the "call to scanf" (see question 12.20). Alternatively, can consume the rest of a partially-read line with a simple code fragment like

while ((c = GetChar ())! = ' \ n ' && c! = EOF)
/* Discard */;

(You may also is able to use the curses flushinp function.)

There is no standard-to-discard unread characters from a stdio input stream. Some vendors do implement Fflush so that Fflush (stdin) discards unread characters, although portable programs cannot depen D on this. (Some versions of the Stdio library implement Fpurge or Fabort calls which do the same thing, but these aren ' t standard, E Ither.) Note, too, that flushing stdio input buffers are not necessarily sufficient:unread characters can also accumulate in other , Os-level input buffers. If you ' re trying to actively discard input (perhaps in anticipation of issuing an unexpected prompt to confirm a destructi ve action, for which an accidentally-typed ' Y ' could is disastrous), you'll have the use of a system-specific technique to D Etect the presence of typed-ahead input; See questions 19.1 and 19.2. Keep in mind the users can become frustrated if you discard input the happened to be typed too quickly.

References:iso Sec. 7.9.5.2
h&amp; S Sec. 15.2

4. A few points to note

    • The fflush operation on the input stream is undefined.
    • No caching does not imply that the input is processed one after another, but that they are immediately available to standard library functions when the operating system returns them. Because there may also be OS-level or even hardware-level caches, these are not setbuf controllable.
    • Also refer to here (I was the first to start from here). And here it is. I extract some important things from the link at the back:

Setbuf () have to do with the delivery of bytes between the
C Library file* Management layer and the OS I/O layer.

Calls to Fread (), fgets (), fgetc (), and GetChar () work within
Whatever file* buffered data is available, and if that data
Is exhausted, the calls request, the file* buffer being refilled
By the system I/O layer.

When full buffering are turned on, that's refill operation results in the
file* layer requesting that the operating system hand it a full
Buffer ' s worth of data; When Buffering was turned off, that
Refill operation results in the file* layer requesting the
Operating system return a single character.

... setting an input stream to be unbuffered
does not tell the operating system to tell the device driver
To go into any kind of "raw" single-character mode. There is
System-specific calls such as IOCTL () and tcsetterm () that
Control what the device driver would do.

Reference: http://www.cppblog.com/lucency/archive/2008/04/07/46419.html

UNIX full-buffered, row-buffered, unbuffered

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.