記事本/編輯器開啟 TXT 檔案時,外部程式寫入新資料,編輯器能自動偵測並重新載入顯示(如 Notepad++ 行為)。
Windows 提供目錄/檔案變更通知機制,可非同步監控特定檔案的 `FILE_NOTIFY_CHANGE_LAST_WRITE` 事件。
// 監控執行緒
DWORD WINAPI MonitorThread(LPVOID lpParam) {
HANDLE hDir = CreateFile(dirPath, FILE_LIST_DIRECTORY,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED, NULL);
OVERLAPPED ol = {0}; ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
BYTE buffer[4096];
while (running) {
DWORD bytes;
if (ReadDirectoryChangesW(hDir, buffer, sizeof(buffer), FALSE,
FILE_NOTIFY_CHANGE_LAST_WRITE, &bytes, &ol, NULL)) {
if (WaitForSingleObject(ol.hEvent, INFINITE) == WAIT_OBJECT_0) {
FILE_NOTIFY_INFORMATION* fni = (FILE_NOTIFY_INFORMATION*)buffer;
do {
if (fni->Action == FILE_ACTION_MODIFIED) {
CString changedFile(fni->FileName, fni->FileNameLength/2);
if (changedFile.CompareNoCase(targetFileName) == 0) {
::PostMessage(hMainWnd, WM_FILE_CHANGED, 0, 0);
}
}
fni = (fni->NextEntryOffset) ? (FILE_NOTIFY_INFORMATION*)((BYTE*)fni + fni->NextEntryOffset) : NULL;
} while (fni);
ResetEvent(ol.hEvent);
}
}
}
CloseHandle(hDir);
return 0;
}
Notepad++ 正是使用 `ReadDirectoryChangesW` 非同步監控,發現外部修改後彈出「檔案已在別處修改,是否重新載入?」對話框。
專業級即時刷新請用 **`ReadDirectoryChangesW` + 非同步 I/O + 完成埠**;輕量工具可用 **定時器輪詢時間戳**。核心在於「監控 → 通知 → 重讀 → 刷新 UI」四步閉環。