C/C++實(shí)現(xiàn)監(jiān)控目錄文件變化
監(jiān)視對(duì)指定目錄的更改,并將有關(guān)更改的信息打印到控制臺(tái),該功能的實(shí)現(xiàn)不僅可以在內(nèi)核層,在應(yīng)用層同樣可以。程序中使用ReadDirectoryChangesW
函數(shù)來(lái)監(jiān)視目錄中的更改,并使用FILE_NOTIFY_INFORMATION
結(jié)構(gòu)來(lái)獲取有關(guān)更改的信息。
ReadDirectoryChangesW 是Windows
操作系統(tǒng)提供的一個(gè)函數(shù),用于監(jiān)視目錄的變化。它屬于Windows API
的一部分,主要用于監(jiān)視文件系統(tǒng)中目錄的修改、新增、刪除等變化,并通過(guò)回調(diào)函數(shù)向應(yīng)用程序提供通知。
以下是該函數(shù)的聲明:
BOOL ReadDirectoryChangesW( HANDLE hDirectory, LPVOID lpBuffer, DWORD nBufferLength, BOOL bWatchSubtree, DWORD dwNotifyFilter, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );
其中:
- hDirectory:要監(jiān)視的目錄的句柄。
- lpBuffer:接收變更通知的緩沖區(qū)。
- nBufferLength:緩沖區(qū)的大小。
- bWatchSubtree:如果為 TRUE,則監(jiān)視目錄樹(shù)中的所有目錄。如果為 FALSE,則僅監(jiān)視指定的目錄。
- dwNotifyFilter:指定要監(jiān)視的變更類(lèi)型,可以是文件夾或文件的新增、刪除、修改等。
- lpBytesReturned:返回實(shí)際讀取到的字節(jié)數(shù)。
- lpOverlapped:用于異步操作的 OVERLAPPED 結(jié)構(gòu)。
- lpCompletionRoutine:指定一個(gè)回調(diào)函數(shù),在異步操作完成時(shí)調(diào)用。
在使用這個(gè)函數(shù)時(shí),通常會(huì)在回調(diào)函數(shù)中處理具體的文件變更信息。ReadDirectoryChangesW
通常用于異步操作,因此在調(diào)用時(shí)需要提供一個(gè)OVERLAPPED
結(jié)構(gòu)或使用同步的方式等待變更。
如下代碼中使用CreateThread
函數(shù)創(chuàng)建一個(gè)線程,并將MonitorFileThreadProc
運(yùn)行起來(lái),此函數(shù)使用帶有FILE_LIST_directory
標(biāo)志的CreateFile
打開(kāi)指定的目錄,該標(biāo)志允許該函數(shù)監(jiān)視目錄。并使用ReadDirectoryChangesW
函數(shù)讀取目錄中的更改,傳遞一個(gè)緩沖區(qū)來(lái)存儲(chǔ)更改,并指定要監(jiān)視的更改類(lèi)型。
使用WideCharToMultiByte
函數(shù)將寬字符文件名轉(zhuǎn)換為多字節(jié)文件名,并將文件名與目錄路徑連接以獲得文件的完整路徑。然后,該功能將有關(guān)更改的信息打印到控制臺(tái)。
#include <stdio.h> #include <Windows.h> #include <tlhelp32.h> DWORD WINAPI MonitorFileThreadProc(LPVOID lParam) { char *pszDirectory = (char *)lParam; BOOL bRet = FALSE; BYTE Buffer[1024] = { 0 }; FILE_NOTIFY_INFORMATION *pBuffer = (FILE_NOTIFY_INFORMATION *)Buffer; DWORD dwByteReturn = 0; HANDLE hFile = CreateFile(pszDirectory, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); if (INVALID_HANDLE_VALUE == hFile) return 1; while (TRUE) { ZeroMemory(Buffer, sizeof(Buffer)); // 設(shè)置監(jiān)控目錄回調(diào)函數(shù) bRet = ReadDirectoryChangesW(hFile,&Buffer,sizeof(Buffer),TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | // 修改文件名 FILE_NOTIFY_CHANGE_ATTRIBUTES | // 修改文件屬性 FILE_NOTIFY_CHANGE_LAST_WRITE, // 最后一次寫(xiě)入 &dwByteReturn, NULL, NULL); if (TRUE == bRet) { char szFileName[MAX_PATH] = { 0 }; // 將寬字符轉(zhuǎn)換成窄字符,寬字節(jié)字符串轉(zhuǎn)多字節(jié)字符串 WideCharToMultiByte(CP_ACP,0,pBuffer->FileName,(pBuffer->FileNameLength / 2), szFileName,MAX_PATH,NULL,NULL); // 將路徑與文件連接成完整文件路徑 char FullFilePath[1024] = { 0 }; strncpy(FullFilePath, pszDirectory, strlen(pszDirectory)); strcat(FullFilePath, szFileName); switch (pBuffer->Action) { case FILE_ACTION_ADDED: { printf("添加: %s \n", FullFilePath); break; } case FILE_ACTION_REMOVED: { printf("刪除: %s \n", FullFilePath); break; } case FILE_ACTION_MODIFIED: { printf("修改: %s \n", FullFilePath); break; } case FILE_ACTION_RENAMED_OLD_NAME: { printf("重命名: %s", szFileName); if (0 != pBuffer->NextEntryOffset) { FILE_NOTIFY_INFORMATION *tmpBuffer = (FILE_NOTIFY_INFORMATION *) ((DWORD)pBuffer + pBuffer->NextEntryOffset); switch (tmpBuffer->Action) { case FILE_ACTION_RENAMED_NEW_NAME: { ZeroMemory(szFileName, MAX_PATH); WideCharToMultiByte(CP_ACP,0,tmpBuffer->FileName, (tmpBuffer->FileNameLength / 2), szFileName,MAX_PATH,NULL,NULL); printf(" -> %s \n", szFileName); break; } } } break; } case FILE_ACTION_RENAMED_NEW_NAME: { printf("重命名(new): %s \n", FullFilePath); break; } } } } CloseHandle(hFile); return 0; } int main(int argc, char * argv[]) { char *pszDirectory = "C:\\"; HANDLE hThread = CreateThread(NULL, 0, MonitorFileThreadProc, pszDirectory, 0, NULL); WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); return 0; }
運(yùn)行后監(jiān)控C盤(pán)所有文件的變化,并輸出如下信息;
到此這篇關(guān)于C/C++實(shí)現(xiàn)監(jiān)控目錄文件變化的文章就介紹到這了,更多相關(guān)C++監(jiān)控目錄文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言中isalnum()函數(shù)和isalpha()函數(shù)的對(duì)比使用
這篇文章主要介紹了C語(yǔ)言中isalnum()函數(shù)和isalpha()函數(shù)的對(duì)比使用,都可以判斷是否為字母但isalnum的判斷還包括數(shù)字,需要的朋友可以參考下2015-08-08C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單翻譯功能
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單翻譯功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01c++如何實(shí)現(xiàn)歸并兩個(gè)有序鏈表
這篇文章主要介紹了c++如何實(shí)現(xiàn)歸并兩個(gè)有序鏈表,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07C++標(biāo)準(zhǔn)庫(kù)中sstream與strstream的區(qū)別詳細(xì)解析
以下是對(duì)C++標(biāo)準(zhǔn)庫(kù)中sstream與strstream的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下2013-09-09基于MFC實(shí)現(xiàn)單個(gè)文檔的文件讀寫(xiě)
這篇文章主要為大家詳細(xì)介紹了如何基于MFC實(shí)現(xiàn)單個(gè)文檔的文件讀寫(xiě)功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)有一定幫助,感興趣的可以了解一下2022-07-07使用C語(yǔ)言實(shí)現(xiàn)CRC校驗(yàn)的方法
本篇文章是對(duì)使用C語(yǔ)言實(shí)現(xiàn)CRC校驗(yàn)的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05