[英]Logging stdin and stdout
有沒有(理想情況下簡單而優雅)的方式來記錄stdin
和stdout
?
請注意,我不打算重定向流。 我希望標准流保持與其他軟件通信的功能,同時還將所有進程間通信寫入某個文件。
正如@PaulR 建議的那樣,您可以使用外部進程,例如 tee(在 Linux/Mac/Unix 上),或者編寫自己的進程以循環讀取 stdin 並寫入 stdout 和另一個文件。
多年前,我用std::basic_ios::rdbuf為std::cout
做過這件事。 所要做的就是定義一個類(參見std::filebuf
和std::streambuf
):
class tee_buf : public std::filebuf {
public:
// Not an owing pointer
tee_buf(std::streambuf * other_stream)
: m_other_stream(other_stream) {}
void swap( tee_buf& rhs );
// No need to override open/close since we need to manage only the file.
// The open/close calls don't touch the other_stream.
protected:
int_type overflow(int_type c = traits_type::eof()) override;
// The parent calls this->overflow(), but then still need to call
// m_other_stream->sync(). This is problematic since m_other_stream
// gets flushed twice.
int sync() override;
pos_type seekoff( off_type off,
std::ios_base::seekdir dir,
std::ios_base::openmode which) override {
return pos_type(off_type(-1)); // ???
}
pos_type seekpos( pos_type sp,
std::ios_base::openmode which) override {
return pos_type(off_type(-1)); // ???
}
....
這對於密集 IO 更有效,因為它避免了中間人。 但在大多數情況下,三通解決方案更簡單、更可取。 如果性能是一個問題(在大多數情況下不是),那么可以讓兩個流緩沖區共享一個內存緩沖區。 也可以使用異步 IO 並行寫入兩個流。
內存泄漏的用法:
std::cout.rdbuf(new tee_buf(std::cout.rdbuf());
無內存泄漏的用法:
編寫一個 RAII 類來包含tee_buf
,以保存原始類並設置新的std::cout.rdbuf()
。 銷毀后恢復std::cout.rdbuf()
的狀態。 創建此類的單個實例,它將在其構造和銷毀時完成骯臟的工作。
至於 C 風格的stdout
:我不相信有辦法覆蓋它的行為。 最多可以使用緩沖存儲器,但這還不足以獲得所需的功能。 對於stdout
,唯一能做的就是使用類似tee
的解決方案。
用tee
做到這一點應該相當簡單。 這將允許您維護任何現有的重定向,同時還將 stdin/stdout 發送到其他地方(在您的情況下發送到文件)。 這也避免了對現有代碼進行任何修改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.