目录
在使用printf或者cout等将数据输出到显示器上时,数据会先进入对应的输出缓冲区,只有当缓冲区被刷新时,数据才会真正来到显示器。
换行符刷新缓冲区(c和c++通用)
#include <iostream>
#include <stdio.h>
#include <unistd.h>
using namespace std;
// 换行符刷新缓冲区
int main()
{
// cout不会直接将“123”输出到显示器上,而是将其发送到输出缓冲区
// 输出缓冲区收到换行符后,会刷新输出缓冲区至显示器上
// 也可以从面向对象的角度思考一下这个问题:
// 我想要输出一些数据到显示器上
// cout用于将数据输出到显示器上
// 可是我想一次发一个完整的数据给显示器,那么什么时候才是这个完整的数据呢
// "\n"告诉cout这个完整的数据我写完了,你去发给显示器吧
cout << 123;
sleep(3);
cout << "\n";
sleep(3);
return 0;
}
输入事件到来(c和c++通用)
#include <iostream>
#include <stdio.h>
#include <unistd.h>
using namespace std;
// 输入事件到来
int main()
{
// 当需要输入时,会刷新输出缓冲区至显示器上
cout << "enter a number: ";
int a;
cin >> a;
return 0;
}
控制符flush(c++特有)
#include <iostream>
#include <stdio.h>
#include <unistd.h>
using namespace std;
// 控制符flush
int main()
{
cout << 123;
sleep(3);
// cout << flush; //--->实际上ostream类对插入运算符<<进行了重载。cout << flush被替换成flush(cout)
flush(cout);
sleep(3);
return 0;
}
控制符endl(c++特有)
#include <iostream>
#include <stdio.h>
#include <unistd.h>
using namespace std;
// 控制符endl
int main()
{
// endl也会刷新cout对应的输出缓冲区至显示器上,并添加换行符'\n'
cout << 123;
sleep(3);
cout << endl;
sleep(3);
return 0;
}
c库函数:fflush刷新缓冲区(c特有)
#include <iostream>
#include <stdio.h>
#include <unistd.h>
using namespace std;
// c库函数:fflush刷新缓冲区
// int fflush(FILE *stream);
int main()
{
// endl也会刷新cout对应的输出缓冲区至显示器上,并添加换行符'\n'
printf("123");
sleep(3);
fflush(stdout);
sleep(3);
return 0;
}
sync(linux)
将所有文件已修改的数据从内核缓冲区写回存储设备;将所有文件的元数据(如文件大小、权限、时间戳等)从内核缓冲区写回存储设备。
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/sync.h>
int main() {
int fd = open("test.txt", O_WRONLY | O_CREAT, 0644);
if (fd == -1) {
perror("open");
return 1;
}
const char *message = "Hello, sync!";
// write并不会把数据直接写入磁盘,而是写入到该文件对应的内核缓冲区
ssize_t bytes_written = write(fd, message, sizeof(message) - 1);
if (bytes_written == -1) {
perror("write");
close(fd);
return 1;
}
// 调用sync函数确保数据写入磁盘
// 刷新所有内核缓冲区,包括这个文件和其他文件对应的内核缓冲区
// 会刷新每个文件对应的内核缓冲区至各自对应的磁盘区域上
sync();
close(fd);
return 0;
}
fsync(linux)
将特定一个文件已修改的数据从内核缓冲区写回存储设备;将特定一个文件的元数据(如文件大小、权限、时间戳等)从内核缓冲区写回存储设备。
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
int main() {
int fd = open("test_fsync.txt", O_WRONLY | O_CREAT, 0644);
if (fd == -1) {
perror("open");
return 1;
}
const char *message = "Hello, fsync!";
ssize_t bytes_written = write(fd, message, sizeof(message) - 1);
if (bytes_written == -1) {
perror("write");
close(fd);
return 1;
}
// 调用fsync函数确保该文件对应内核缓冲区数据和元数据写入磁盘
if (fsync(fd) == -1) {
perror("fsync");
close(fd);
return 1;
}
close(fd);
return 0;
}
这里,在写入数据后,我们调用 fsync
。fsync
会确保不仅文件内容(数据)被写入磁盘,而且文件的元数据,如文件大小、权限、时间戳等也被同步更新到磁盘。这对于需要严格一致性的应用场景非常重要,比如文件系统的元数据更新操作。
fdatasync
(linux)
只保证将特定一个文件对应的内核缓冲区中的数据写入到磁盘。
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
int main() {
int fd = open("test_fdatasync.txt", O_WRONLY | O_CREAT, 0644);
if (fd == -1) {
perror("open");
return 1;
}
const char *message = "Hello, fdatasync!";
ssize_t bytes_written = write(fd, message, sizeof(message) - 1);
if (bytes_written == -1) {
perror("write");
close(fd);
return 1;
}
// 调用fdatasync函数确保该文件内核缓冲区数据写入磁盘
if (fdatasync(fd) == -1) {
perror("fdatasync");
close(fd);
return 1;
}
close(fd);
return 0;
}