我正在編寫單元測試,並試圖找到一種方法來測試我的類是否已正確關閉文件句柄(它使用舊式open()和關())。理想情況下,我希望能夠在不訪問實際句柄的情況下執行此操作 - 我希望能夠檢查文件系統中的文件並確定它是否當前在其他地方打開。如何確定文件是否已關閉
我試過通過獨佔文件鎖來做它,但我沒有多少運氣。此外,文件鎖定非常不跨平臺(這需要在Solaris,Linux和Windows上運行)。
有什麼建議嗎?
我正在編寫單元測試,並試圖找到一種方法來測試我的類是否已正確關閉文件句柄(它使用舊式open()和關())。理想情況下,我希望能夠在不訪問實際句柄的情況下執行此操作 - 我希望能夠檢查文件系統中的文件並確定它是否當前在其他地方打開。如何確定文件是否已關閉
我試過通過獨佔文件鎖來做它,但我沒有多少運氣。此外,文件鎖定非常不跨平臺(這需要在Solaris,Linux和Windows上運行)。
有什麼建議嗎?
如果你依賴於打開/關閉這樣的文件,這不是一個適當的單元測試 - 這種測試可能由於各種原因而隨機失敗,從而導致誤報和普遍混淆。
相反,考慮抽象文件操作並確保在文件的表示形式上調用close。
無法檢查文件句柄是否仍然打開。
如果你使用C++,你可以簡單地總是使用RAII,你不必擔心未關閉的文件句柄。
否則,你永遠不能調用系統API,而是調用你的包裝器API。每當你打開你可以添加一個向量的路徑,你關閉你的一切都可以刪除該路徑。最後,檢查你的矢量是否有零大小。
您可以用select
和poll
查詢。選擇將返回EBADF
如果文件描述符被關閉:
fd_set rfds;
struct timeval tv = { 0, 1 };
int retval;
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
retval = select(1, &rfds, NULL, NULL, &tv);
if (retval == -1 && errno == EBADF)
// File is closed
注意,我已經沒有測試代碼,但文檔講述了這一點。
此外,這並不完全準確,因爲errno也可能是EBADF,原因不同。
編輯:另一件事:如果你在關閉另一個文件後立即打開一個文件,它很可能與前一個文件具有相同的fd,所以如果你想檢查是否所有文件都已關閉,這隻能用於半體面。
當然,如果文件已關閉,但是另一個文件已打開並碰巧被分配了相同的文件描述符(這很可能,在給定文件描述符分配策略的情況下),這將不起作用。 – 2010-12-14 00:08:10
@亞當是的,但不能真正幫助。但是,如果它只是想檢查是否所有文件都已關閉,那麼它就可以工作。但我會添加它,謝謝。 – terminus 2010-12-14 00:09:34
在Unix/Solaris/Linux中,如果您知道pid,則可以檢查/proc/
pid /fd/*
。您也可以掃描所有/ proc/*/fd條目。
對於Windows,我會研究一下sysinternals.com工具ProcMon,現在叫做Process Monitor。我不記得是否曾經有可用的源代碼。
如果您想知道某個文件系統中的給定文件是否由該機器上的某個進程打開,那麼有一個有用的工具叫做lsof,它可以告訴您各種unix和unix系統。
點好。 – 2010-12-14 15:52:07