Check the output result of calling the API that buffers the string in the program that writes it to the file first, and then the system call that does not buffer. Since the API buffers, the character string output by the system call is output first.
[root@vagrant-centos65 buff]# cat /etc/centos-release
CentOS release 6.5 (Final)
It is a process of passing a file as a parameter and writing a character string to that file.
buffer.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
FILE *f;
char *apiStr = "Hello, API\n";
char *systemCallStr = "Hello, system call\n";
if((f = fopen(argv[1], "w")) == NULL) {
puts("fopen error");
exit(1);
}
//fputs are buffered
fputs(apiStr, f);
//The system call write is not buffered, so it is output immediately.
if (write(fileno(f), systemCallStr, strlen(systemCallStr)) < 0) exit(1);
fclose(f);
exit(0);
}
[root@vagrant-centos65 buff]# gcc -o buffer buffer.c
[root@vagrant-centos65 buff]# ./buffer buffer.txt
[root@vagrant-centos65 buff]# cat buffer.txt
Hello, system call
Hello, API
no_buffer1.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
FILE *f;
char *apiStr = "Hello, API\n";
char *systemCallStr = "Hello, system call\n";
if((f = fopen(argv[1], "w")) == NULL) {
puts("fopen error");
exit(1);
}
//Set not to buffer
//Alternatively, fflush is OK after fputs
setbuf(f, NULL);
//Immediate output
fputs(apiStr, f);
//Immediate output
if (write(fileno(f), systemCallStr, strlen(systemCallStr)) < 0) exit(1);
fclose(f);
exit(0);
}
[root@vagrant-centos65 buff]# gcc -o no_buffer1 no_buffer1.c
[root@vagrant-centos65 buff]# ./no_buffer1 no_buffer1.txt
[root@vagrant-centos65 buff]# cat no_buffer1.txt
Hello, API
Hello, system call
The file descriptor and FILE can be moved back and forth freely, but it seems that you should not mix the two easily because the buffer may cause the input / output order to be out of order.
The printf should be buffered, but the API is printed before the system call. [Addition] From the comment of angel_p_57
The output stream that references the terminal device is always buffered line by line by default.
no_buffer2.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
char *apiStr = "Hello, API\n";
char *systemCallStr = "Hello, system call\n";
printf("%s", apiStr);
if (write(STDOUT_FILENO, systemCallStr, strlen(systemCallStr)) < 0) exit(1);
exit(0);
}
[root@vagrant-centos65 buff]# gcc -o no_buffer2 no_buffer2.c
[root@vagrant-centos65 buff]# ./no_buffer2
Hello, API
Hello, system call
[Normal Linux programming 2nd edition: The royal road of gcc programming that can be learned from the mechanism of Linux](https://www.amazon.co.jp/%E3%81%B5%E3%81%A4%E3%81%86% E3% 81% AELinux% E3% 83% 97% E3% 83% AD% E3% 82% B0% E3% 83% A9% E3% 83% 9F% E3% 83% B3% E3% 82% B0-% E7 % AC% AC2% E7% 89% 88-Linux% E3% 81% AE% E4% BB% 95% E7% B5% 84% E3% 81% BF% E3% 81% 8B% E3% 82% 89% E5 % AD% A6% E3% 81% B9% E3% 82% 8Bgcc% E3% 83% 97% E3% 83% AD% E3% 82% B0% E3% 83% A9% E3% 83% 9F% E3% 83 % B3% E3% 82% B0% E3% 81% AE% E7% 8E% 8B% E9% 81% 93-% E9% 9D% 92% E6% 9C% A8-% E5% B3% B0% E9% 83 % 8E-ebook / dp / B075ST51Y5)
Recommended Posts