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

How should I read the filename in FILE_NOTIFY_INFORMATION struct

本文关键字:FILE NOTIFY INFORMATION 文件名 结构 何读取 读取 我应该      更新时间:2023-10-16

我正在尝试监视文件更改,但我不确定如何读取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 changedn";
            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. 根据ReadDirectoryChangesW函数的文档,缓冲区需要DWORD对齐。当您在堆栈上使用缓冲区时,这不能保证 - 您应该从堆中分配一个缓冲区。

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

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

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

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

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