需先用isatty(STDOUT_FILENO)检查stdout是否连终端,返回0则退出;再用freopen("app.log", "a+", stdout)重定向;最后调用setvbuf设置缓冲策略,且必须在首次输出前完成。

将C++程序运行时的printf、cout等标准输出内容自动写入本地日志文件,同时保留系统级缓冲(如行缓冲或全缓冲)行为,避免频繁磁盘I/O导致性能下降。
确认当前stdout是否已连接终端
执行isatty(STDOUT_FILENO)判断:返回1说明连着终端,可安全重定向;返回0说明stdout已被重定向过,再次操作可能覆盖原有流,【务必先检查,否则日志会丢失】。
在main函数开头插入:#include <unistd.h> 和 if (isatty(STDOUT_FILENO) == 0) return -1;。
用freopen安全替换stdout流
调用freopen("app.log", "a+", stdout),以追加读写模式打开日志文件并绑定到stdout。
立即学习“C++免费学习笔记(深入)”;
这一步会关闭原stdout对应的文件描述符,并用新打开的文件描述符替代——注意:必须用"a+"而非"w",否则每次启动都会清空历史日志;"a+"保证光标始终在文件末尾,且支持fseek回溯读取。
如果返回NULL,说明文件无法打开,需检查目录是否存在、权限是否足够。
设置系统级缓冲策略
方法一:启用行缓冲(推荐用于调试日志)
调用setvbuf(stdout, NULL, _IOLBF, 0),让每次遇到换行符就刷一次磁盘,兼顾实时性与效率。
方法二:启用全缓冲(适合高吞吐批量输出)
调用setvbuf(stdout, NULL, _IOFBF, 8192),指定8KB缓冲区,满或显式fflush时才写入磁盘。
方法三:禁用缓冲(仅限极低延迟场景)
调用setvbuf(stdout, NULL, _IONBF, 0),每条输出立即落盘——但会显著拖慢程序,慎用。
【setvbuf必须在freopen之后、首次输出之前调用】,否则无效。
验证重定向是否生效
第一步:输出测试字符串printf("LOG_TEST: init ok\n");;
第二步:立即调用fflush(stdout)强制刷出缓冲区;
第三步:在终端执行tail -n1 app.log,确认该行已写入文件。
若未出现,检查app.log所在目录是否有写权限,或是否被其他进程独占锁定。


















