我建议查看出色的Far Manager的源代码。它的内部查看器可以轻松处理数千兆字节的文件,显示正在写入的文件没有问题,并且几乎可以实时更新更改的文件内容。我从未注意到正在显示的文件有任何阻塞问题。
与问题相关的源代码似乎在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()
(最终导致API调用)。不使用重叠。SetFilePointerEx
ReadFile