sysctl -a | grep dirty
vm.dirty_writeback_centisecs
500 → 5 秒vm.dirty_expire_centisecs
3000 → 30 秒vm.dirty_background_ratio / vm.dirty_background_bytes
vm.dirty_ratio / vm.dirty_bytes
cat /proc/meminfo | grep -E 'Dirty|Writeback'
Dirty: 当前脏页大小(还没刷到磁盘的数据)Writeback: 正在刷往磁盘的数据watch -n1 "cat /proc/meminfo | grep -E 'Dirty|Writeback'"
ps aux | grep flush
root ..... [flush-253:0]
iotop -o
#include <fstream>
#include <string>
/**
* @brief 将字符串保存到文件
* @param file_path 文件路径
* @param content 要保存的字符串
* @param is_append 是否追加写入(true=追加,false=覆盖)
* @return 保存成功返回true,失败返回false
*/
bool saveStringToFile(const std::string& file_path, const std::string& content, bool is_append = false) {
// 确定打开模式
std::ios::openmode mode = is_append ? std::ios::app : std::ios::out;
std::ofstream out_file(file_path, mode);
if (!out_file.is_open()) return false;
out_file << content;
out_file.close();
return true;
}
// 使用示例
int main() {
// 覆盖写入
saveStringToFile("demo.txt", "第一行内容\n第二行内容", false);
// 追加写入
saveStringToFile("demo.txt", "\n追加的内容", true);
return 0;
}
std::ofstream + << 运算符,最简单通用;write() 方法;fstream 没有直接暴露文件描述符 (fd),但要调用系统 fsync(int fd) 强制数据落盘,必须拿到 fd。fsync(fd) 是系统调用,必须依赖文件描述符(Linux/macOS)/ 文件句柄(Windows)fstream 获取 fd 的接口,但主流编译器都提供了扩展方法ostream::flush() 刷新用户态缓冲区,再用 fsync 刷内核缓冲区,才能真正落盘basic_filebuf 提供 fd() 方法直接获取文件描述符:#include <fstream>
#include <unistd.h> // fsync 头文件
bool syncToDisk(std::fstream& fs) {
// 1. 先刷新C++流缓冲区到内核
fs.flush();
// 2. 获取文件描述符
int fd = fs.rdbuf()->fd();
if (fd == -1) return false;
// 3. 调用fsync强制落盘
return ::fsync(fd) == 0;
}
_fileno + FlushFileBuffers 替代 fsync:#include <fstream>
#include <windows.h>
bool syncToDisk(std::fstream& fs) {
// 1. 刷新流缓冲区
fs.flush();
// 2. 获取文件句柄
int fd = fs.rdbuf()->fd();
HANDLE hFile = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
if (hFile == INVALID_HANDLE_VALUE) return false;
// 3. Windows强制落盘
return FlushFileBuffers(hFile) != 0;
}
#include <fstream>
#include <cstdlib>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
// 强制 fstream 数据写入磁盘(真正落盘,不丢数据)
bool fstream_fsync(std::fstream& file) {
if (!file.is_open()) return false;
// 第一步:刷新C++流缓冲区到操作系统内核
file.flush();
// 第二步:获取文件描述符
int fd = file.rdbuf()->fd();
if (fd < 0) return false;
// 第三步:系统级强制落盘
#ifdef _WIN32
HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
return FlushFileBuffers(handle) != FALSE;
#else
return ::fsync(fd) == 0;
#endif
}