0

我正在尝试监视文件更改,但我不确定如何读取 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");
    }

有什么我做错了吗

4

1 回答 1

3

你有一些我可以立即看到的问题:

  1. 根据该ReadDirectoryChangesW函数的文档,缓冲区需要DWORD对齐。当您在堆栈上使用缓冲区时,这不能保证 - 您应该从堆中分配一个。

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

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

编辑:由于您在问题中添加了更多代码,现在很明显您正在混合这两个 API。FindFirstChangeNotification并且FindNextChangeNotification是一个 API,并且ReadDirectoryChangesW是另一个。我相信您对文档中的这段话感到困惑:

此函数不指示满足等待条件的更改。要在通知中检索有关特定更改的信息,请使用 ReadDirectoryChangesW 函数。

我想你的困惑是可以理解的,但是这两个 API 不能一起使用。如果您正在使用,FindFirstChangeNotification那么您得到的只是通知内容发生了变化,您必须重新阅读目录以找出它是什么。如果您想要文件级别的特定通知,那么您必须使用它ReadDirectoryChangesW来进行监控。

于 2015-06-15T04:05:12.523 回答