写入c-style stdout / stderr时的通知?

时间:2016-10-07 18:39:30

标签: c++ qt

我正在创建一个捕获所有控制台输出并将其转储到一个日志中的类。我需要这个,因为我的程序使用了许多我无法改变的第三方库。来自这些库的有用信息以少数方式打印到控制台。我知道使用cout将自定义流缓冲区替换为cerr / rdbuf。我不需要帮助。我也知道创建一个管道来捕获c风格的输出,例如fprintf( stdout, "Hello, world!" )。但是,与我可以处理输出的自定义流缓冲区不同,c风格的输出现在卡在此管道中,我必须定期刷新所有内容并从中读取。我更愿意收到通知或安装回调来处理管道输入。

Qt也在这里。我一直在玩QSocketNotifier类,但似乎没有使用管道读取或写入文件描述符。

建议?

2 个答案:

答案 0 :(得分:1)

  

输出现在卡在此管道中,我必须定期清除所有内容并从中读取。我更愿意收到通知或安装回调来处理管道输入。

不清楚什么"一切"是或者为什么你需要做的不仅仅是刷新特定的文件流,但这听起来像你指的是这些流是缓冲的,所以连接它们的管道都不会被写入,直到满足冲洗条件为止或flush()已执行。

此外,我们不知道您是在操纵第3层文件流还是第2层文件描述符。我们不知道您是否已禁用C ++流和第3层流之间的同步。

所有这一切,可以用

禁用C层3缓冲
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);

这意味着您不再需要flush(),例如,fprintf()来电写入管道。

为此,您可以设置轮询/选择调用以检查管道上的数据,或者您可以让线程执行阻塞读取并将数据传输到其他位置。

答案 1 :(得分:0)

在Linux上,我们使用重定向标准流:

freopen (outfile, "a", stdout);
freopen (outfile, "a", stderr);

我不相信有任何方式可以收到通知。