首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

Windows 目錄監控:ReadDirectoryChangesW 實作

     編輯:C++ 入門

Windows 目錄監控程式實作

利用 Windows API ReadDirectoryChangesW 實現即時監控目錄下的文件變更(建立、刪除、重命名、屬性變更、寫入等)。

程式介面

目錄監控介面

核心代碼邏輯

BOOL bRet = FALSE;
BYTE Buffer[1024]; // 緩衝區接收變更通知
CDirectoryWatchDlg *pDlg = (CDirectoryWatchDlg*)lpParameter;
FILE_NOTIFY_INFORMATION *pBuffer = (FILE_NOTIFY_INFORMATION*)Buffer;
DWORD dwBytesReturned = 0;

// 開啟目錄句柄,需指定 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED
HANDLE hFile = CreateFile(pDlg->m_strDirectoryPath.GetBuffer(),
    FILE_LIST_DIRECTORY,
    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    NULL, OPEN_EXISTING,
    FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
    NULL);

if (INVALID_HANDLE_VALUE == hFile) {
    // 錯誤處理
    return 0;
}

// 更新 UI 狀態
pDlg->GetDlgItem(IDC_BUTTON_START)->EnableWindow(FALSE);
pDlg->GetDlgItem(IDC_BUTTON_STOP)->EnableWindow(TRUE);

ZeroMemory(Buffer, sizeof(Buffer));

// 循環讀取目錄變更
while (bRet = ReadDirectoryChangesW(hFile, &Buffer, sizeof(Buffer), TRUE,
    FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_LAST_WRITE,
    &dwBytesReturned, NULL, NULL)) {

    if (!bRet) break; // 錯誤或停止

    pBuffer = (FILE_NOTIFY_INFORMATION*)Buffer;
    while (TRUE) {
        CString strType, strInfo;
        switch (pBuffer->Action) {
            case FILE_ACTION_ADDED: strType = _T("新增"); break;
            case FILE_ACTION_REMOVED: strType = _T("刪除"); break;
            case FILE_ACTION_MODIFIED: strType = _T("修改"); break;
            case FILE_ACTION_RENAMED_OLD_NAME: strType = _T("重命名(舊)"); break;
            case FILE_ACTION_RENAMED_NEW_NAME: strType = _T("重命名(新)"); break;
        }
        strInfo = pBuffer->FileName; // 檔名 (Unicode)
        // 將變更資訊加入列表控件顯示
        int nIndex = pDlg->m_ctrlDirectoryWatchLog.GetItemCount();
        pDlg->m_ctrlDirectoryWatchLog.InsertItem(nIndex, strType);
        pDlg->m_ctrlDirectoryWatchLog.SetItemText(nIndex, 1, strInfo);

        if (pBuffer->NextEntryOffset == 0) break;
        pBuffer = (FILE_NOTIFY_INFORMATION*)((BYTE*)pBuffer + pBuffer->NextEntryOffset);
    }
    ZeroMemory(Buffer, sizeof(Buffer));
}

CloseHandle(hFile);

關鍵點說明

  • ReadDirectoryChangesW 為同步/非同步均可,範例使用同步阻塞模式。
  • 需開啟目錄句柄時指定 FILE_FLAG_BACKUP_SEMANTICS 以允許開啟目錄。
  • 緩衝區大小需足夠,否則可能漏掉事件;單次調用可能返回多筆記錄,需透過 NextEntryOffset 遍歷。
  • 監控標誌:FILE_NOTIFY_CHANGE_FILE_NAME (建立/刪除/重命名)、FILE_NOTIFY_CHANGE_ATTRIBUTES、FILE_NOTIFY_CHANGE_LAST_WRITE (內容修改) 等。
  • UI 更新需在主執行緒,若在工作執行緒需用 PostMessage 或同步機制。

下載連結

完整專案原始碼:百度網盤下載

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved