码迷,mamicode.com
首页 > 其他好文 > 详细

文件监控——ReadDirecotryChangesW

时间:2020-05-19 00:31:59      阅读:65      评论:0      收藏:0      [点我收藏+]

标签:判断   box   删除文件   ati   权限   false   this   new   句柄   

实现原理:

  实现文件监控操作的核心函数是ReadDirecotryChangesW。这个API函数可以设置监控目录、过滤条件,从而获取监控数据。在调用API函数ReadDirecotryChangesW设置监控过滤条件之前,需要先通过CreateFile函数打开监控目录,获取监控目录的句柄。之后才能调用ReadDirecotryChangesW函数设置监控过滤条件并阻塞,直到有满足监控过滤条件的操作,ReadDirecotryChangesW才会返回监控数据继续往下执行。接下来便根据返回的监控数据,判断操作类型以及获取相关数据。

  注意:调用一次ReadDirectoryChangesW函数,只会监控一次。要想实现持续监控,则需要程序循环调用ReadDirectoryChangesW函数来设置监控并获取监控数据。由于持续的目录监控需要不停循环调用ReadDirecotryChangesW函数进行设置监控和获取监控数据,所以,如果把这段代码放在主线程中,则可能会导致程序阻塞。为了解决主线程阻塞的问题,可以创建一个文件监控子线程,把文件监控的实现代码放到子线程中运行

实现过程:

  (1).打开目录,获取文件句柄(必须要用FILE_LIST_DIRECTORY 权限与FILE_FLAG_BACKUP_SEMANTICS标志)

  (2).设置目录监控

  (3).判断文件操作类型

实现代码:

//开启监控按钮
void CFileMonitDlg::OnBnClickedButton1()
{
    // TODO: 在此添加控件通知处理程序代码

    UpdateData(TRUE);

    //检测文件是否存在
    if (GetFileAttributes(m_Edit_Path) == INVALID_FILE_ATTRIBUTES)
    {
        MessageBox(_T("文件不存在 请重试!"));
        return;
    }

    USES_CONVERSION;
    //创建线程
    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MonitorFileThreadProc, this, 0, NULL);

    return;
}


// 目录监控多线程
UINT MonitorFileThreadProc(LPVOID lpVoid)
{
    CFileMonitDlg* ptrData = (CFileMonitDlg*)lpVoid;
    CString temp;
    temp = ptrData->m_Edit_Path + L"\\";

    // 打开目录, 获取文件句柄
    HANDLE hDirectory = ::CreateFile(temp.GetBuffer(), FILE_LIST_DIRECTORY,
        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
        FILE_FLAG_BACKUP_SEMANTICS, NULL);
    if (INVALID_HANDLE_VALUE == hDirectory)
    {

        MessageBoxA(0, "CreateFileA Error", "Error", MB_OK);
        return 1;
    }

    DWORD dwBufferSize = 4096;
    // 申请一个足够大的缓冲区 
    BYTE* pBuf = new BYTE[dwBufferSize];
    if (NULL == pBuf)
    {
        MessageBoxA(0, "new Error", "Error", MB_OK);
        return 2;
    }

    FILE_NOTIFY_INFORMATION* pFileNotifyInfo = (FILE_NOTIFY_INFORMATION *)pBuf;
    
    BOOL bRet = FALSE;
    DWORD dwRet = 0;
    CString res = L"";
    // 开始循环设置监控
    do
    {
        ::RtlZeroMemory(pFileNotifyInfo, dwBufferSize);
        // 设置监控目录
        bRet = ::ReadDirectoryChangesW(hDirectory,
            pFileNotifyInfo,
            dwBufferSize,
            TRUE,
            FILE_NOTIFY_CHANGE_FILE_NAME |
            FILE_NOTIFY_CHANGE_ATTRIBUTES |
            FILE_NOTIFY_CHANGE_LAST_WRITE,
            &dwRet,
            NULL, NULL);
        if (FALSE == bRet)
        {
            MessageBoxA(0, "ReadDirectoryChangesW Error", "Error", MB_OK);
            break;
        }

        // 判断操作类型并显示
        switch (pFileNotifyInfo->Action)
        {
            //新增文件
        case FILE_ACTION_ADDED:
        {
            temp.Format(_T("%s:%s\r\n"), _T("新增文件"), pFileNotifyInfo->FileName);
            res += temp + L"\r\n";
            break;
        }
            //删除文件
        case FILE_ACTION_REMOVED:
        {
            temp.Format(_T("%s:%s\r\n"), _T("删除文件"), pFileNotifyInfo->FileName);
            res += temp + L"\r\n";
            break;
        }
            //修改文件
        case FILE_ACTION_MODIFIED:
        {
            temp.Format(_T("%s:%s\r\n"), _T("修改文件"), pFileNotifyInfo->FileName);
            res += temp + L"\r\n";
            break;
        }
            //重命名文件
        case FILE_ACTION_RENAMED_OLD_NAME:
        {
            temp.Format(_T("%s:%s\r\n"), _T("重命名前文件"), pFileNotifyInfo->FileName);
            res += temp + L"\r\n";
            break;
        }
        case FILE_ACTION_RENAMED_NEW_NAME:
        {
            temp.Format(_T("%s:%s\r\n"), _T("重命名后文件"), pFileNotifyInfo->FileName);
            res += temp + L"\r\n";
            break;
        }
        default:
            break;
        }

        SetDlgItemText(ptrData->m_hWnd,IDC_EDIT2, res);

    } while (bRet);



    // 关闭句柄, 释放内存
    CloseHandle(hDirectory);
    delete[] pBuf;

    return 0;
}

 

文件监控——ReadDirecotryChangesW

标签:判断   box   删除文件   ati   权限   false   this   new   句柄   

原文地址:https://www.cnblogs.com/ndyxb/p/12913790.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!