在Qt应用程序中将标准输出重定向到文件

3
我有一个使用Qt编写的应用程序,它启动了多个QProcess子进程,并调用QProcess::setChannelMode(QProcess::ForwardedChannels)。我想将此应用程序的标准输出(现在包含其子进程的标准输出)转发到一个日志文件中,该文件的位置由应用程序确定,这意味着我不能简单地修改我的日志记录以同时写入指定的文件,因为这对于子进程是行不通的,而且我也不能运行app | tee logfile,因为我不知道tee到哪里去了。
如果有 - 我更喜欢通过Qt实现这一点的方法(如果存在的话-我还没有找到),但其他解决方案也是可以接受的。
3个回答

4

这不只是QProcess::setStandardOutputFile()吗?

抱歉,我自己从未实际操作过。


这对于一个包含多个进程的文件能够工作吗?也就是说,它们都能够写入文件并且它们的输出会按顺序出现吗? - spbots
他们可能都可以写入同一个文件,但我不知道使用了什么底层锁定 - 如果它们同时运行,你可能会混淆进程中的消息。 - Martin Beckett
QProcess方法的问题在于: 1)我还需要原始应用程序的输出,但作为QProcess,我无法访问它。 2)我认为这与多个进程同时写入同一文件不兼容。 - Matt
@Matt:我认为没有不需要更改所有子进程代码(添加进程间同步)的解决方案可以解决(2)。 - smerlin

1

好的。作为一种非Qt解决方案,看起来freopen将会做我需要的事情:

#include <cstdio>
...
QString logFile;
...
freopen(logFile.toLocal8Bit().data(), "w", stdout);

我怀疑如果多个进程同时写入,这将无法正常工作。C库函数不提供任何锁定功能,除非明确要求,否则底层操作系统API也不会提供此类锁定机制。如果这解决了您的问题,可能是因为您的日志记录仅在低频率下发生,因此问题高度不太可能出现。 - smerlin

1

1
看起来更改 std::cout.rdbuf() 只对在 std::cout 上执行的操作有效 - 例如来自 printf 或子进程的输出不会被转发。 - Matt
@Matt,printf调用将采用不同的路线,上述内容仅适用于cout/cerr等。除非您实现某种形式的IPC(即使使用下面的freopen解决方案),否则您将无法获得连贯的输出... 不幸的是,如果您希望从多个进程写入同一日志文件,则需要实现某种自定义记录器,该记录器通过套接字工作,例如,并且有一个单独的进程负责将接收到的内容写入文件。您还可以查看boost iostreams库... - Nim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接