[英]Reading a File while it is being written by another process
我正在嘗試從緩沖區文件中讀取二進制數據,該文件由不同的進程(我無法修改)連續寫入。 我正在使用以下代碼打開文件:
fileH = CreateFileA((LPCSTR)filename,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
它正確打開,沒有錯誤。 但是,當我從文件中讀取數據時,它似乎阻止了其他進程寫入文件,因為我丟失了數據。
緩沖區是循環的,這意味着文件大小是固定的,並且新數據不斷寫入緩沖區中的舊數據。
編輯:有時最瑣碎的解決方案有效......
我已經聯系了這家軟件公司並告訴他們這個bug,並在一天之內發布了一個帶有修復程序的新版本。 對不起,這不適用於所有人。
如果不知道寫入過程是如何打開文件的話,很難說出你的選擇。 顯然,它不會打開文件進行獨占訪問並保持打開狀態。 否則你將無法閱讀它。
您描述的行為表明寫入過程打開文件以進行獨占訪問,寫入文件,然后關閉文件。 如果是這種情況,那么您無法讓程序打開文件並保持打開狀態。 這會導致寫入過程在嘗試寫入時失敗。
如果你不能修改寫作過程,那么你的選擇是有限的,不是很有吸引力。 最有可能的是,你必須讓程序打開文件,讀取一小塊文件,關閉文件,然后再等一會兒再讀一遍。 即使這樣,也無法保證在寫入過程嘗試寫入時您不會打開文件。 我想,你已經發現了。
您是否知道寫入過程在無法打開文件時是丟失數據,還是只是緩沖數據並在下次實際打開文件時寫入數據? 如果是這種情況,那么我建議逐步瀏覽文件可能會有效。 否則,您將丟失數據。
沒有開放模式,我知道這相當於“打開文件進行閱讀,但如果有人想要獨占訪問,那就讓他們擁有它。”
另一種可能性是讓程序在您想要讀取時重命名該文件,然后在讀取之后刪除重命名的文件。 當然,這假設寫入過程將在必要時創建新文件。 即使這樣,如果寫入過程在您重命名時嘗試寫入,也可能會出現問題。 我認為這不是一個問題(就文件系統而言,重命名可能是原子的),但這是你必須要研究的東西。
我建議查看優秀遠程經理的源代碼。 它的內部查看器可以輕松處理數GB的文件,顯示正在寫入的文件沒有問題,幾乎可以實時更新更改的文件內容。 我從未注意到正在顯示的文件存在任何阻塞問題。
與問題相關的源代碼似乎位於viewer.cpp文件中。
一個有趣的事情是它不使用GENERIC_READ
:
ViewFile.Open(strFileName, FILE_READ_DATA, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, nullptr, OPEN_EXISTING);
我懷疑在這里刪除SYNCHRONIZE
可能很重要。
文件更改檢測在Viewer::ProcessKey
, KEY_IDLE
情況下:
// Smart file change check -- thanks Dzirt2005
//
bool changed = (
ViewFindData.ftLastWriteTime.dwLowDateTime!=NewViewFindData.ftLastWriteTime.dwLowDateTime ||
ViewFindData.ftLastWriteTime.dwHighDateTime!=NewViewFindData.ftLastWriteTime.dwHighDateTime ||
ViewFindData.nFileSize != NewViewFindData.nFileSize
);
if ( changed )
ViewFindData = NewViewFindData;
else {
if ( !ViewFile.GetSize(NewViewFindData.nFileSize) || FileSize == static_cast<__int64>(NewViewFindData.nFileSize) )
return TRUE;
changed = FileSize > static_cast<__int64>(NewViewFindData.nFileSize); // true if file shrank
}
緩存文件讀取在cache.cpp中實現。 但是那里沒有什么真正驚天動地的,只有一些Seek()
和Read()
( 最終導致 SetFilePointerEx
和ReadFile
API調用)。 OVERLAPPED未使用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.