I. buffer mechanism based on the application's access to files, that is, whether there is a buffer. access to files can be divided into operations with a buffer and non-buffer file operations: the advanced file system will automatically open up the memory buffer for the files in use in the user space... information & nbs
I. buffer mechanism
Based on the access method of the application to the file, that is, whether there is a buffer, access to the file can be divided into operations with a buffer and non-buffer file operations:
Buffer file operations: the advanced file system automatically opens a memory buffer for the files being used in the user space.
Non-buffer file system: a low-level file system. if needed, you can only set a buffer for each file in your own program.
If you use a non-buffered file access method, you must use the read/write file system to process this operation each time you perform a read/write operation on the file. therefore, if you need to access a disk file, you must execute a system call every time you access it. a system call will involve switching the CPU status, that is, switching from the user space to the kernel space, context switching will consume a certain amount of CPU time, and frequent disk access will significantly affect the program execution efficiency.
ANSI standard C library functions are built on underlying system calls, that is, the implementation of C library file access functions uses low-level file I/O system calls, in order to reduce the number of system calls and improve efficiency, the file processing functions in the ANSI standard C library adopt the buffer mechanism according to different applications. in this way, when reading disk files, you can read a large amount of data from the file to the buffer zone at a time. in the future, you do not need to use the system to call this feature, that is, you only need a small amount of CPU status switching. When writing a file, you can first store the content in a buffer. after the file is fully written, or when an update is required, you can call the system call to write the file to the disk once.
II. buffer type
Standard I/O provides three types of buffers.
1. Full Buffer: This buffer must be filled with the entire buffer before I/O system calling is performed. For disks
Files are usually accessed using a full buffer. When I/O operations are performed for the first time, ANSI-standard file management functions call
The malloc function gets the buffer to be used. The default size is 8192.
// Come from/usr/include/stdio. h
/* Default buffer size .*/
# Ifndef BUFSIZ
# Define BUFSIZ _ IO_BUFSIZ // global macro definition of BUFSIZ
# Endif
// Come from/usr/include/libio. h
# Define _ IO_BUFSIZ _ G_BUFSIZ
// Come from/usr/include/_ g_config.h
# Define _ G_BUFSIZ 8192 // actual size
The refresh operation is the write operation of the standard I/O buffer. It can be automatically completed by the system (when it is filled with a slow
Or call the fflush () or flush () function.
2. row buffer: In this case, when a line break is encountered in the input and output, the standard I/O library executes I/O
System call operation. When a stream involves a terminal (such as standard input and standard output), the row buffer is used. Because the buffer length of each row collected by the standard I/O library is fixed, as long as the buffer is filled up, even if there is no line break, the I/O system call operation will be executed. The default row buffer size is 128 bytes.
3. no buffer: the standard I/O library does not cache characters. If you use a standard I/O function to write a few characters to
In the buffer stream, it is equivalent to using the write system to call the function to write these characters to the Associated open file. The standard error stream stderr usually does not contain a buffer, which allows the error information to be displayed as soon as possible.
For standard input/output devices, ansi c requires the following buffer features:
L standard input and standard output devices: the standard input stream and standard output mode are used only when no interaction device is involved.
The outbound traffic is the full buffer zone.
L standard error output device: the standard error will never be a full buffer zone.
For any given stream, you can call the setbuf () and setvbuf () functions to change its buffer type.
1,
Name ::
Setbuf
Function:
Change the buffer location of the file stream
Header file:
# Inlcude
Original function:
Void setbuf (FILE * restrict stream, char * restrict buf)
Parameters:
Stream object to be operated
Buffer specified by buf
Return value:
If the request succeeds, 0 is returned. if the request fails, 0 is returned.
The first parameter of this function is the stream object to be operated, and the second parameter buf must point to a BUFSIZ
Buffer zone. If the buf is set to NULL, the buffer is disabled.
If the execution is successful, 0 is returned; otherwise, a non-0 value is returned.
2,
Name ::
Setvbuf
Function:
Change the buffer location of the file stream
Header file:
# Inlcude
Original function:
Int setvbuf (FILE * restrict stream, char * restrict buf, int modes, size_t n)
Parameters:
Stream object to be operated
Buffer specified by buf
Mode buffer type
N buf size
Return value:
If the request succeeds, 0 is returned. if the request fails, 0 is returned.
/* Make STREAM use buffering mode MODE. If BUF is not NULL, use N bytes of it for buffering; else allocate an internal buffer N bytes long .*/
The first parameter of this function is the stream object to be operated; the second parameter buf must point to a BUFSIZ
Buffer; the third parameter is the buffer type, which is defined as follows:
// Come from/usr/include/stdio. h
/* The possibilities for the third argument to 'setvbuf '.*/
# Define _ IOFBF 0/* Fully buffered. * // Full Buffer
# Define _ IOLBF 1/* Line buffered. * // row buffer
# Define _ IONBF 2/* No buffering. * // No buffer
Fourth parameter
The size of the buf. If you specify a stream without a buffer, the buf and size parameters are ignored.
If you specify a full or row buffer, buf and size can specify a buffer and its length. If you specify that the stream has a buffer while the buf is NULL, the standard I/O library will automatically allocate an appropriate buffer length for the stream, which is the value specified by the st_blksize member of the file attribute data structure (struct stat, if the system cannot determine this value for the stream (for example, if the stream involves a device or a pipe), a buffer with the length of BUFSIZ is allocated.
If this function is successfully executed, 0 is returned; otherwise, a non-0 value is returned.
The following is an instance program for modifying buf case files. The source code is as follows:
View plainint main (int argc, char ** argv)
{
Int I;
FILE * fp;
Char msg1 [] = "hello, wolrd/n ";
Char msg2 [] = "hello/nworld ";
Char buf [128];
/* Open (or create) a file, use setbuf to set it to nobuf, and check the current stream before closing */
If (fp = fopen ("no_buf1.txt", "w") = NULL)
{
Perror ("file open failure! ");
Return (-1 );
}
Setbuf (fp, NULL); // Set to no buf
Fwrite (msg1, 7, 1, fp); // write content
Printf ("test setbuf (no buf )! Check no_buf1.txt/n "); // check the buf status
Printf ("press enter to continue! /N ");
Getchar ();
Fclose (fp); // Close the stream, so it will write back to buf (if there is a buf)
/Open (or create) a file, use setvbuf to set it to nobuf, and check the current stream before closing */
If (fp = fopen ("no_buf2.txt", "w") = NULL)
{
Perror ("file open failure! ");
Return (-1 );
}
Setvbuf (fp, NULL, _ IONBF, 0); // Set to no buf
Fwrite (msg1, 7, 1, fp); // write content
Printf ("test setvbuf (no buf )! Check no_buf2.txt/nbecause line buf, only before
Enter data write/n ");
Printf ("press enter to continue! /N ");
Getchar ();
Fclose (fp); // Close the stream, so it will write back to buf (if there is a buf)
/* Open (or create) a file, use setvbuf to set it to row buf, and check whether the current stream is closed */
If (fp = fopen ("l_buf.txt", "w") = NULL)
{
Perror ("file open failure! ");
Return (-1 );
}
Setvbuf (fp, buf, _ IOLBF, sizeof (buf); // Set it to row buf
Fwrite (msg2, sizeof (msg2), 1, fp); // write content
Printf ("test setvbuf (line buf )! Check l_buf.txt, because line buf,
Only data before enter send to file/n ");
Printf ("press enter to continue! /N ");
Getchar ();
Fclose (fp); // Close the stream, so it will write back to buf
// Open (or create) a file, use setvbuf to set it to full buf, and check whether the current stream is closed.
If (fp = fopen ("f_buf.txt", "w") = NULL)
{
Perror ("file open failure! ");
Return (-1 );
}
Setvbuf (fp, buf, _ IOFBF, sizeof (buf ));
For (I = 0; I
{
Fputs (msg1, fp );
}
Printf ("test setbuf (full buf )! Check f_buf.txt/n ");
Printf ("press enter to continue! /N ");
Getchar ();
Fclose (fp); // Close the stream, so it will write back to buf
}
The compilation process and running results are as follows:
[Root @ localhost linux_app] #./setbuf_example
Test setbuf (no buf )! Check no_buf1.txt // upload the content of no_buf1.txt in the current directory before pressing the enter key.
Press enter to continue!
Test setvbuf (no buf )! Check no_buf2.txt // first click the content of no_buf2.txt in the previous directory before pressing the enter key
Because line buf, only before enter data write
Press enter to continue!
Test setvbuf (line buf )! Check l_buf.txt, because line buf, only data before enter send to file
Press enter to continue! // Set the content of the l_buf.txt file in the current directory before pressing the enter key.
Test setbuf (full buf )! Check f_buf.txt
Press enter to continue! // Upload the f_buf.txt content in the current directory before pressing the enter key
The following describes how to view the content of each file during the process:
[Root @ localhost linux_app] # cat no_buf1.txt
Hello, w // All 7 characters written to the file
[Root @ localhost linux_app] # cat no_buf2.txt
Hello, w // All 7 characters written to the file
[Root @ localhost linux_app] # cat l_buf.txt
Hello // only the characters before the carriage return are written
[Root @ localhost linux_app] # cat f_buf.txt // No content is written
After the running process is completed:
[Root @ localhost linux_app] # cat no_buf1.txt
Hello, w // same as the original content
[Root @ localhost linux_app] # cat no_buf2.txt
Hello, w // same as the original content
[Root @ localhost linux_app] # cat l_buf.txt
Hello
World // because the fclose () function is called, the buffer is refreshed and the world is written
[Root @ localhost linux_app] # cat f_buf.txt
Hello
World // because the fclose () function is called, the buffer is refreshed and hello/nworld is written.