VC++ ReadDirectoryChangesW对文件目录实施监控

转载:https://blog.csdn.net/weixin_34087301/article/details/86326249

记得之前写过一篇文章关于对目录监控,但当时是下载网上的源码,没仔细研究,只知道核心用到ReadDirectoryChangesW这个函数,最近项目中有需要用到监控目录变化,在此写一下,加深印象。

BOOL WINAPI ReadDirectoryChangesW(
    __in         HANDLE hDirectory,
    __out        LPVOID lpBuffer,
    __in         DWORD nBufferLength,
    __in         BOOL bWatchSubtree,
    __in         DWORD dwNotifyFilter,
    __out_opt    LPDWORD lpBytesReturned,
    __inout_opt  LPOVERLAPPED lpOverlapped,
    __in_opt     LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
 );
#include <iostream>
#include <windows.h>

void MonitorDir(char* file, bool bIncludeSubdirectories = false)
{
    int        nBufferSize = 1024;
    char*    buffer = new char[nBufferSize];
    HANDLE  hDirectoryHandle = NULL;


    hDirectoryHandle = ::CreateFileA(
        file,
        FILE_LIST_DIRECTORY,
        FILE_SHARE_READ
        | FILE_SHARE_WRITE
        | FILE_SHARE_DELETE,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_BACKUP_SEMANTICS
        | FILE_FLAG_OVERLAPPED,
        NULL);

    if (hDirectoryHandle == INVALID_HANDLE_VALUE)
        return;

    printf("Monitor.....
");
    while (1)
    {
        DWORD dwBytes = 0;

        memset(buffer, 0, nBufferSize);

        if (!::ReadDirectoryChangesW(
            hDirectoryHandle,
            buffer,
            nBufferSize,
            bIncludeSubdirectories,
            FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_FILE_NAME,
            &dwBytes,
            NULL,
            NULL) || GetLastError() == ERROR_INVALID_HANDLE)
        {
            break;
        }

        if (!dwBytes)
        {
            printf("Buffer overflow~~
");
        }

        PFILE_NOTIFY_INFORMATION record = (PFILE_NOTIFY_INFORMATION)buffer;
        DWORD cbOffset = 0;

        do
        {
            switch (record->Action)
            {
            case FILE_ACTION_ADDED:
                printf("FILE_ACTION_ADDED:");
                break;
            case FILE_ACTION_REMOVED:
                printf("FILE_ACTION_REMOVED:");
                break;
            case FILE_ACTION_MODIFIED:
                printf("FILE_ACTION_MODIFIED:");
                break;
            case FILE_ACTION_RENAMED_OLD_NAME:
                printf("FILE_ACTION_RENAMED_OLD_NAME:");
                break;

            case FILE_ACTION_RENAMED_NEW_NAME:
                printf("FILE_ACTION_RENAMED_NEW_NAME:");
                break;

            default:
                break;
            }

            char fileBuffer[512];

            WideCharToMultiByte(CP_ACP, 0, record->FileName, record->FileNameLength, fileBuffer, record->FileNameLength, NULL, NULL);
            printf(fileBuffer);
            printf("
");

            cbOffset = record->NextEntryOffset;
            record = (PFILE_NOTIFY_INFORMATION)((LPBYTE)record + cbOffset);
        } while (cbOffset);
    }

    delete buffer;

    if (hDirectoryHandle)
        CloseHandle(hDirectoryHandle);
}


int main()
{
    MonitorDir("C:\Users\Administrator\Desktop\新建文件夹");
    getchar();
    return 0;
}

测试:

1、在新建文件夹里面新建一个txt文本文件

2、对txt文本文件进行重命名

3、对txt文本文件删除

原文地址:https://www.cnblogs.com/chechen/p/14603665.html