2010-11-13 30 views
0

我基本上試圖從wfilebuf派生,所以我可以輸出到一個文件並攔截輸出以將其打印到控制檯/調試窗口以及如下圖所示: http://savingyoutime.wordpress.com/2009/04/21/和/或在這裏:http://savingyoutime.wordpress.com/2009/04/22/40/試圖從wfilebuf(filebuf)獲取日誌

(古支持此觀點:http://www.horstmann.com/cpp/streams.txt

我幾乎得到了它,但我似乎無法能夠既寫在底層的文件和PEEK輸入。

我重寫sync()函數類似於第二個例子,但似乎pbase()和pptr()總是NULL,除非我用setp(...)設置緩衝區,但這似乎打破了文件輸出。該文件始終爲空!

我在這個原油的嘗試低於:

class LoggerBuffer : public wfilebuf { 
// Functions 
    public: 
     LoggerBuffer(); 
     ~LoggerBuffer(); 
     void open(const wchar_t loggerFile[]); 
     void close(); 
     int sync(); 
     int_type overflow(int_type c = EOF); 
     void setState(int newState); 
// Variables 
    private: 
     int currentState; 
     static const int BUFFER_SIZE = 10; 
     wchar_t buffer[BUFFER_SIZE]; 
}; 

class LoggerStream : public wostream { 
// Functions 
    public: 
     LoggerStream(); 
     ~LoggerStream(); 
     void open(const wchar_t loggerFile[] = 0); 
     void close(); 
     void setState(int newState); 
}; 

LoggerBuffer::LoggerBuffer() { 
    wfilebuf::open("NUL", wios::out); currentState = 1; 
} 
LoggerBuffer::~LoggerBuffer() { 
    wcout << "Destruction of LoggerBuffer" << endl; 
} 
void LoggerBuffer::open(const wchar_t loggerFile[]) { 
    wcout << "LoggerBuffer Opening " << loggerFile << endl; 
    close(); 
    wfilebuf* temp = wfilebuf::open(loggerFile, wios::out); //ios::out | ios::app | ios::trunc 
    setp (buffer, buffer+(BUFFER_SIZE-1)); 
} 
void LoggerBuffer::close() { 
    wfilebuf::close(); 
} 

int LoggerBuffer::sync() { 
    wcout << " Syncing "; 
    int out_waiting = pptr() - pbase(); 
    wcout << out_waiting << " characters!"; 
    wcout << endl; 
    wcout << "pptr(): " << (unsigned int)pptr() << endl; 
    return wfilebuf::sync(); 
} 
LoggerBuffer::int_type LoggerBuffer::overflow(int_type c) { 
    wcout << "overflow! (" << (wchar_t)c << ")" << endl; 
    if (c == EOF) 
     return EOF; 
    if (sync() == EOF) 
     return EOF; 
    return wfilebuf::overflow(c); 
} 
void LoggerBuffer::setState(int newState) { 
    wcout << "New buffer state = " << newState << endl; 
    currentState = newState; 
} 

LoggerStream::LoggerStream() : wostream(new LoggerBuffer), wios(0) { 
} 
LoggerStream::~LoggerStream() { 
    delete rdbuf(); 
} 
void LoggerStream::open(const wchar_t loggerFile[]) { 
    wcout << "LoggerStream Opening " << loggerFile << endl; 
    ((LoggerBuffer*)rdbuf())->open(loggerFile); 
} 
void LoggerStream::close() { 
    ((LoggerBuffer*)rdbuf())->close(); 
} 
void LoggerStream::setState(int newState) { 
    wcout << "New stream state = " << newState << endl; 
    ((LoggerBuffer*)rdbuf())->setState(newState); 
} 

全面披露:我就問類似的東西前面一個問題:我想雖然我已經解決了這個問題Simple wostream logging class (with custom stream manipulators)

任何幫助,非常感謝!謝謝!

+0

我比較接受的構圖會比在這裏繼承的構建更可重用的類。仍然找不到錯誤:( – Basilevs 2010-11-13 12:37:46

+0

您是否爲緩衝區區域設置和標準流區域設置設置了適當的codecvt?您是否嘗試輸出ASCII字符串? – Basilevs 2010-11-15 06:45:43

回答

0

我會使用filtering streambuf,它不會自行緩衝,而是將數據傳遞給每個目標的實際流緩衝(即,實際緩衝)。這應該簡化你的代碼,讓你專注於你真正關心的部分。

+0

雖然非緩衝streambufs實際上更容易實現,但它們可能會有性能問題。 – Basilevs 2010-11-13 12:35:30

+0

@Basilevs:如果你是在沒有緩衝的情況下寫入一個實際的文件,那會導致一個問題 - 但在這種情況下,你只需要寫入另一個緩衝區。通過一個體面的編譯器可以內聯函數調用, – 2010-11-13 15:37:58

+0

對於虛擬調用沒有內聯,還需要注意的是,由你鏈接的實現假設在流的每個字節上調用溢出函數,這就是我的意思 - 你應該儘量減少如果你想在大數據流上獲得良好的性能,可以使用許多函數調用。因此,最好重寫xsputn。 – Basilevs 2010-11-13 20:48:46