我应该如何读取FILE_NOTIFY_INFORMATION结构中的文件名

时间:2015-06-15 03:55:41

标签: c++ winapi filesystems file-monitoring readdirectorychangesw

我正在尝试监控文件更改,但我不确定如何读取FILE_NOTIFY_INFORMATION结构中的文件名:

    HANDLE dwChangeHandles[2];
    DWORD dwWaitStatus;
    wChangeHandles[0] = FindFirstChangeNotification(dirname.c_str(), FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE);
    if (dwChangeHandles[0] == INVALID_HANDLE_VALUE) printerr(__FILE__,__LINE__,"FindFirstChangeNotification function failed.\n");
    ...
    if ((dwChangeHandles[0] == NULL) || (dwChangeHandles[1] == NULL))  //final validation
        printerr(__FILE__,__LINE__,"Unexpected NULL from FindFirstChangeNotification.\n");

    while (TRUE) {
        std::cout << "Waiting for notification...\n";
        dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles, FALSE, INFINITE);
        if(dwWaitStatus==WAIT_OBJECT_0){
            std::cout << "Something changed\n";

            DWORD BytesReturned;
            size_t bufLen = 1024;
            FILE_NOTIFY_INFORMATION buffer[bufLen];
            if (ReadDirectoryChangesW(dwChangeHandles[0], buffer, bufLen, FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE, &BytesReturned, NULL, NULL)){
                std::wcout << std::wstring(buffer->FileName)<< std::endl; //THERE IS NOTHING IN THE EXPECTED OUTPUT HERE
            }
            if (FindNextChangeNotification(dwChangeHandles[0]) == FALSE ) printerr(__FILE__,__LINE__,"FindNextChangeNotification function failed.\n");
        }

        else if(dwWaitStatus==WAIT_TIMEOUT) printerr(__FILE__,__LINE__,"No changes in the timeout period.\n");
        else printerr(__FILE__,__LINE__,"Unhandled dwWaitStatus.\n");
    }

我做错了什么

1 个答案:

答案 0 :(得分:2)

您可以立即看到许多问题:

  1. 根据ReadDirectoryChangesW函数的文档,缓冲区需要DWORD - 对齐。由于您在堆栈上使用缓冲区,因此无法保证 - 您应该从堆中分配一个缓冲区。

  2. 您似乎没有正确使用此功能。通常,您会先调用ReadDirectoryChangesW,然后然后等待事件。不是相反。当ReadDirectoryChangesW返回异步调用时,缓冲区中通常没有数据。在使用缓冲区内容之前,您需要等待请求已完成的通知。

  3. FindNextChangeNotification仅与FindFirstChangeNotification一起使用,因此这是完全错误的。完成ReadDirectoryChangesW后,您需要使用FILE_NOTIFY_INFORMATION结构中的NextEntryOffset字段来循环返回的事件。

  4. 修改:由于您已经在问题中添加了更多代码,现在很明显您正在混合使用这两个API。 FindFirstChangeNotificationFindNextChangeNotification是一个API,ReadDirectoryChangesW是另一个API。我相信你对文档中的这段话感到困惑:

      

    此功能不表示满足等待的更改   条件。检索有关特定更改的信息作为一部分   通知,使用ReadDirectoryChangesW函数。

    我想你的困惑是可以理解的,但这两个API不能一起使用。如果您使用的是FindFirstChangeNotification,那么您收到的是某些内容更改的通知,您必须重新阅读该目录才能找到它的内容。如果您需要文件级别的特定通知,则必须使用ReadDirectoryChangesW进行监控。