2011-11-28 70 views
1

我正在運行一個windows C++多線程應用程序,其中服務器類的一個實例/線程附加到該文件。其他線程運行客戶端實例,它們僅在每個客戶端啓動時才加載文件 。 當我在加載文件結束時的2k字節範圍內時,我檢查文件的大小是否已更改爲 ,因此我知道要更新要讀取的總字節數。偶爾文件大小 我回來錯誤地被確定爲零(0)。我正在使用下面的統計調用。當返回零時,然後作爲完整性檢查,然後調用getFileSizeWithTellg()以查看它返回的內容,並返回預期的非零值。與初始值相同或更大的值。 我意識到,轉換爲無符號整數可能會有問題,但文件不會大於5毫比特大小的文件是 。爲什麼stat()調用返回文件大小爲零的錯誤值(0)?

什麼可能導致stat()調用返回一個零值,當..Tellg調用不? 感謝您對此的任何洞察。

/

/ snippets from methods in different classes 
// 
// from client class 
ifstream fileSeqIn 
fileSeqIn.open(fName.c_str(), ios::in | ios::binary |ios::ate); 
// to get initial size 
size = fileSeqIn.tellg(); 
fileSeqIn.seekg(0, ios::beg); 


// later to determine if the file has grown 
struct stat filestatus; 
unsigned int size; 
if (stat(fName, &filestatus) == 0) { 
    size = (unsigned int)filestatus.st_size; 
} 

// 
unsigned int getFileSizeWithTellg(char *fname) 
{ 
    // get length of file 
    is.open (fname, ios::binary); 
    is.seekg (0, ios::end); 
    length = is.tellg(); 
    is.close(); 
    return(length); 
} 


//----------------------------------------------------------------------------- 
// from server class 
ofstream fileSeqOut; 
fileSeqOut.open(fName.c_str(), ios::app | ios::out |ios::ate |ios::binary); 

回答

1

一個顯著差異:stat返回文件大小的系統的視圖; tellg返回流的內部狀態的值依賴。文件庫流會被緩衝,並且在刷新或關閉文件之前,數據可能不會傳遞到系統。如果您在調用stat之前刷新了數據流,您是否也獲得了相同的區別?

+0

更具體一點:stat()調用返回FindFirstFileEx返回的文件大小 - 這個信息在文件關閉之前是不可靠的。 –

+0

這是相當隨機的。但寫完後我並沒有臉紅。但現在我是。另外,在負載開始時,我使用tellg。當我接近尾聲時,我使用統計信息,因爲它不會更改文件指針位置,而我需要移動到文件的ed,然後調用tellg並將其重新定位到我所在的位置,這只是更多一點的代碼。但這可能是一條路。在書寫線上的每次寫入都應該正常工作後,請結合沖洗。正確? –

+0

如果您想獲得關於文件狀態的準確信息並且擁有文件句柄,請調用使用句柄的API,而不是使用文件名的API。通常,使用文件名的API將比使用句柄的API更準確(句柄總是反映文件狀態的最新文件系統度量)。 –

1

如果拉里奧斯特曼說是真的,使用GetFileInformationByHandle可能會解決問題。

+1

您或任何其他人都可以通過在MSVS安裝目錄中的某處檢查「crt-src \ stat.c」來驗證Osterman先生是否確實說出了真相。 – user786653

+0

我沒有看到奧斯特曼先生的評論。他們在哪? –

+0

One * minor *使用GetFileInformationByHandle注意 - 我相信它需要爲FILE_QUERY_INFORMATION訪問打開文件 - 如果您打開GENERIC_READ文件,這將毫無問題地工作,但是如果您只打開GENERIC_WRITE文件,它就會獲得「T。 –